Procházet zdrojové kódy

#2382 Audit for site actions

RomanL před 7 roky
rodič
revize
27ddadc386

+ 19 - 1
inc/classes/BxDolAccount.php

@@ -292,7 +292,12 @@ class BxDolAccount extends BxDolFactory implements iBxDolSingleton
         );
 
         $aTemplate = BxDolEmailTemplates::getInstance()->parseTemplate('t_Confirmation', $aPlus);
-        return $aTemplate && sendMail($sEmail, $aTemplate['Subject'], $aTemplate['Body'], 0, array(), BX_EMAIL_SYSTEM);
+        $bRv = $aTemplate && sendMail($sEmail, $aTemplate['Subject'], $aTemplate['Body'], 0, array(), BX_EMAIL_SYSTEM);
+        
+        if($bRv){
+            $this->doAudit($iAccountId, '_sys_audit_action_account_resend_confirmation_email');
+        }
+        return $bRv;
     }
 
     /**
@@ -545,6 +550,8 @@ class BxDolAccount extends BxDolFactory implements iBxDolSingleton
        // create system event
         bx_alert('account', 'delete', $this->_iAccountID, 0, array ('delete_with_content' => $bDeleteWithContent));
         
+        $this->doAudit($this->_iAccountID, $bDeleteWithContent ? '_sys_audit_action_account_deleted_with_content' : '_sys_audit_action_account_deleted');
+        
         return true;
     }
 
@@ -591,6 +598,17 @@ class BxDolAccount extends BxDolFactory implements iBxDolSingleton
         $a = $this->getInfo();
         return md5($a['email'] . $a['salt'] . BX_DOL_SECRET);
     }
+    
+    public function doAudit($iAccountId, $sAction, $aData = array())
+    {
+        $iAccountId = (int)$iAccountId ? (int)$iAccountId : $this->_iAccountID;
+        bx_audit(
+            $iAccountId, 
+            'bx_accounts', 
+            $sAction,  
+            array('content_title' => $this->getDisplayName(), 'data' => $aData)
+        );
+    }
 
     /**
      * @return CHECK_ACTION_RESULT_ALLOWED if access is granted or error message if access is forbidden.

+ 6 - 0
inc/classes/BxDolAcl.php

@@ -579,6 +579,12 @@ class BxDolAcl extends BxDolFactory implements iBxDolSingleton
         $oZ = new BxDolAlerts('profile', 'set_membership', '', $iProfileId, array('mlevel'=> $iLevelId, 'period' => $mixedPeriod['period'], 'period_unit' => $mixedPeriod['period_unit'], 'starts_now' => $bStartsNow, 'txn_id' => $sTransactionId));
         $oZ->alert();
 
+        // audit
+        $aDataForAudit = array();
+        if (!is_empty($aMembershipCurrent))
+            $aDataForAudit = array('new_membership_level' => _t($aLevel['name']), 'old_membership_level' => _t($aMembershipCurrent['name']));
+        BxDolProfile::getInstance($iProfileId)->doAudit('_sys_audit_action_set_membership', $aDataForAudit);
+        
         // Send notification
         $aTemplate = BxDolEmailTemplates::getInstance()->parseTemplate('t_MemChanged', array('membership_level' => _t($aLevel['name'])), 0, $iProfileId);
         if ($aTemplate)

+ 45 - 0
inc/classes/BxDolCmts.php

@@ -1102,6 +1102,13 @@ class BxDolCmts extends BxDolFactory implements iBxDolReplaceable, iBxDolContent
             $this->isRemoveAllowed($aCmt, true);
 
             $this->deleteMetaInfo ($iCmtId);
+            
+            bx_audit(
+               $this->getId(), 
+               $this->_aSystem['module'], 
+               '_sys_audit_action_delete_comment',  
+               $this->_prepareAuditParams($iCmtId, array('comment_author_id' => $aCmt['cmt_author_id'], 'comment_text' => $aCmt['cmt_text']))
+           );
 
             bx_alert($this->_sSystem, 'commentRemoved', $iObjId, $iPerformerId, array(
                 'object_author_id' => $iObjAthrId,
@@ -1183,6 +1190,13 @@ class BxDolCmts extends BxDolFactory implements iBxDolReplaceable, iBxDolContent
             'comment_author_id' => $aCmt['cmt_author_id'], 
             'comment_text' => $aCmt['cmt_text']
         ));
+        
+        bx_audit(
+           $this->getId(), 
+           $this->_aSystem['module'], 
+           '_sys_audit_action_add_comment',  
+           $this->_prepareAuditParams($iCmtId, array('comment_author_id' => $aCmt['cmt_author_id'], 'comment_text' => $aCmt['cmt_text']))
+       );
 
         bx_alert('comment', 'added', $iCmtId, $iPerformerId, array(
             'object_system' => $this->_sSystem, 
@@ -1241,6 +1255,13 @@ class BxDolCmts extends BxDolFactory implements iBxDolReplaceable, iBxDolContent
             'comment_author_id' => $aCmt['cmt_author_id'], 
             'comment_text' => $aCmt['cmt_text']        	
         ));
+        
+        bx_audit(
+           $this->getId(), 
+           $this->_aSystem['module'], 
+           '_sys_audit_action_edit_comment',  
+           $this->_prepareAuditParams($iCmtId, array('comment_author_id' => $aCmt['cmt_author_id'], 'comment_text' => $aCmt['cmt_text']))
+       );
 
         bx_alert('comment', 'edited', $iCmtId, $iPerformerId, array(
             'object_system' => $this->_sSystem, 
@@ -1491,6 +1512,30 @@ class BxDolCmts extends BxDolFactory implements iBxDolReplaceable, iBxDolContent
         $aDp['dynamic_mode'] = isset($aDp['dynamic_mode']) ? (bool)$aDp['dynamic_mode'] : false;
         $aDp['show_empty'] = isset($aDp['show_empty']) ? (bool)$aDp['show_empty'] : false;
     }
+    
+    protected function _prepareAuditParams($iId, $aData)
+    {
+        $sModule = $this->_aSystem['module'];
+        $oModule = BxDolModule::getInstance($sModule);
+        $CNF = $oModule->_oConfig->CNF;
+
+        $aContentInfo = BxDolRequest::serviceExists($sModule, 'get_all') ? BxDolService::call($sModule, 'get_all', array(array('type' => 'id', 'id' => $this->getId()))) : array();
+        $iContextId = 0;
+        if (!empty($aContentInfo)){
+            $iContextId = isset($CNF['FIELD_ALLOW_VIEW_TO']) && (!empty($aContentInfo[$CNF['FIELD_ALLOW_VIEW_TO']]) && (int)$aContentInfo[$CNF['FIELD_ALLOW_VIEW_TO']] < 0) ? - $aContentInfo[$CNF['FIELD_ALLOW_VIEW_TO']] : 0; 
+        }
+        
+        $AuditParams = array(
+            'content_title' => $this->getObjectTitle() ,
+            'context_profile_id' => $iContextId,
+            'content_info_object' =>  isset($CNF['OBJECT_CMTS_CONTENT_INFO']) ? $CNF['OBJECT_CMTS_CONTENT_INFO'] : '',
+            'data' => array_merge(array('comment_id' => $iId), $aData)
+        );
+        if ($iContextId > 0)
+            $AuditParams['context_profile_title'] = BxDolProfile::getInstance($iContextId)->getDisplayName();
+        
+        return $AuditParams;
+    }
 
     protected function _prepareTextForOutput ($s, $iCmtId = 0)
     {

+ 19 - 0
inc/classes/BxDolCronAudit.php

@@ -0,0 +1,19 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+* Copyright (c) UNA, Inc - https://una.io
+* MIT License - https://opensource.org/licenses/MIT
+*
+* @defgroup    UnaCore UNA Core
+* @{
+*/
+
+class BxDolCronAudit extends BxDolCron
+{
+    public function processing()
+    {
+        BxDolDb::getInstance()->query(BxDolDb::getInstance()->prepare("DELETE FROM `sys_audit` WHERE FROM_UNIXTIME(`added`) < NOW() - INTERVAL ? DAY", (int)getParam("sys_audit_days_before_expire")));
+        BxDolDb::getInstance()->query("DELETE FROM `sys_audit` WHERE `id` < (SELECT MAX(`m`.`id`) FROM (SELECT `id` FROM `sys_audit` ORDER BY `id` DESC LIMIT " . (int)getParam("sys_audit_max_records")) . ") `m`)");
+    }
+}
+
+/** @} */

+ 23 - 0
inc/classes/BxDolFeature.php

@@ -165,6 +165,13 @@ class BxDolFeature extends BxDolObject
             
         if(!$bPerformUndo)
             $this->isAllowedFeature(true);
+        
+        bx_audit(
+            $this->getId(), 
+            $this->_aSystem['name'], 
+            '_sys_audit_action_' . ($bPerformUndo ? 'un' : '') . 'feature',  
+            $this->_prepareAuditParams()
+        );
 
         bx_alert($this->_sSystem, ($bPerformUndo ? 'un' : '') . 'feature', $iObjectId, $iAuthorId, array('object_author_id' => $iObjectAuthorId));
         bx_alert('feature', ($bPerformUndo ? 'un' : '') . 'do', 0, $iAuthorId, array('object_system' => $this->_sSystem, 'object_id' => $iObjectId, 'object_author_id' => $iObjectAuthorId));
@@ -187,6 +194,22 @@ class BxDolFeature extends BxDolObject
     {
     	return $bPerformed && $this->isUndo() ? '_feature_do_unfeature' : '_feature_do_feature';
     }
+    
+    private function _prepareAuditParams()
+    {
+        $sModule = $this->_aSystem['name'];
+        $oModule = BxDolModule::getInstance($sModule);
+        $CNF = $oModule->_oConfig->CNF;
+
+        $aContentInfo = BxDolRequest::serviceExists($sModule, 'get_all') ? BxDolService::call($sModule, 'get_all', array(array('type' => 'id', 'id' => $this->getId()))) : array();
+        
+        $AuditParams = array(
+            'content_title' => isset($CNF['FIELD_TITLE'])  ? $aContentInfo[$CNF['FIELD_TITLE']] : '',
+            'content_info_object' =>  isset($CNF['OBJECT_CONTENT_INFO']) ? $CNF['OBJECT_CONTENT_INFO'] : '',
+        );
+        
+        return $AuditParams;
+    }
 }
 
 /** @} */

+ 12 - 0
inc/classes/BxDolProfile.php

@@ -488,6 +488,16 @@ class BxDolProfile extends BxDolFactory implements iBxDolProfile
         return $this->changeStatus(BX_PROFILE_STATUS_PENDING, 'disapprove', $iAction, $iProfileId, $bSendEmailNotification);
     }
 
+    public function doAudit($sAction, $aData = array())
+    {
+        bx_audit(
+            $this->getContentId(), 
+            $this->getModule(), 
+            $sAction,  
+            array('content_title' => $this->getDisplayName(), 'data' => $aData)
+        );  
+    }
+    
     /**
      * Change profile status to 'Suspended'
      */
@@ -516,6 +526,8 @@ class BxDolProfile extends BxDolFactory implements iBxDolProfile
         // alert about status changing
         bx_alert('profile', $sAlertActionName, $iProfileId, false, array('action' => $iAction));
         
+        $this->doAudit('_sys_audit_action_set_status_' . $sStatus);
+        
         // send email to member about status change
         if ($bSendEmailNotification)
             sendMailTemplate('t_ChangeStatus' . ucfirst($sStatus), $oAccount->id(), $iProfileId, array('status' => $sStatus), BX_EMAIL_SYSTEM);

+ 12 - 10
inc/utils.inc.php

@@ -1380,22 +1380,22 @@ function bx_unicode_urldecode($s)
 
 /**
  * Raise an audit event
- * @param int $iProfileId - sender (action's author) profile id, if it is false - then currectly logged in profile id is used
  * @param int $iContentId - content id
  * @param string $sContentModule - module name
  * @param string $sAction - system action key
- * @param string $sContentTitle - needed in case when original content was deleted
- * @param string $sContentInfoObject - content info object
- * @param int $iContextProfileId - context profile id
- * @param string $sContextProfileTitle - needed in case when original context was deleted
- * @param array $aActionParams - serialized array of parameters to pass to 'action lang key', for example friend name in case if 'befriend' action
+ * @param array $aParams - array of parameters 
  */
 function bx_audit($iContentId, $sContentModule, $sAction, $aParams)
 {
-    $sContentTitle = $sContentInfoObject = $sContextProfileTitle = $sData = $sActionParams = '';
-    $iContextProfileId = 0;
+    if (!getParam('sys_audit_enable') || getParam('sys_audit_acl_levels') == '')
+        return;
     
     $iProfileId = bx_get_logged_profile_id();
+    if (!BxDolAcl::getInstance()->isMemberLevelInSet(explode(',', getParam('sys_audit_acl_levels')), $iProfileId))
+        return;
+    
+    $sContentTitle = $sContentInfoObject = $sContextProfileTitle = $sData = $sActionParams = '';
+    $iContextProfileId = 0;
     
     if (isset($aParams['profile_id']))
         $iProfileId = (int)$aParams['profile_id'];
@@ -1418,9 +1418,11 @@ function bx_audit($iContentId, $sContentModule, $sAction, $aParams)
     if (isset($aParams['data']) && is_array($aParams['data']) && count($aParams['data']))
         $sData = serialize($aParams['data']);
     
+    $sProfileTitle = BxDolProfile::getInstance($iProfileId)->getDisplayName();
+    
     $oDb = BxDolDb::getInstance();
-    $sSql = $oDb->prepare("INSERT INTO `sys_audit`(`added`, `profile_id`, `content_id`, `content_title`, `content_module`, `context_profile_id`, `context_profile_title`, `action_lang_key`, `action_lang_key_params`, `content_info_object`, `extras`) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"
-     ,time(), $iProfileId, $iContentId, $sContentTitle, $sContentModule, $iContextProfileId, $sContextProfileTitle, $sAction, $sActionParams ,$sContentInfoObject, $sData);
+    $sSql = $oDb->prepare("INSERT INTO `sys_audit`(`added`, `profile_id`, `profile_title`, `content_id`, `content_title`, `content_module`, `context_profile_id`, `context_profile_title`, `action_lang_key`, `action_lang_key_params`, `content_info_object`, `extras`) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"
+     ,time(), $iProfileId, $sProfileTitle, $iContentId, $sContentTitle, $sContentModule, $iContextProfileId, $sContextProfileTitle, $sAction, $sActionParams ,$sContentInfoObject, $sData);
     return !$oDb->query($sSql);
 }
 

+ 16 - 3
install/sql/system.sql

@@ -352,8 +352,7 @@ INSERT INTO `sys_options`(`category_id`, `name`, `caption`, `value`, `type`, `ex
 (@iCategoryId, 'sys_site_splash_enabled', '', '', 'checkbox', '', '', '', 26),
 
 (@iCategoryId, 'sys_site_cover_common', '', '0', 'digit', '', '', '', 27),
-(@iCategoryId, 'sys_unit_cover_profile', '', '0', 'digit', '', '', '', 28),
-(@iCategoryId, 'sys_audit_max_records', '', '1000', 'digit', '', '', '', 29);
+(@iCategoryId, 'sys_unit_cover_profile', '', '0', 'digit', '', '', '', 28);
 
 
 --
@@ -568,6 +567,18 @@ INSERT INTO `sys_options`(`category_id`, `name`, `caption`, `value`, `type`, `ex
 (@iCategoryId, 'sys_twilio_gate_token', '_adm_stg_cpt_option_sys_twilio_gate_token', '', 'digit', '', '', '', 2),
 (@iCategoryId, 'sys_twilio_gate_from_number', '_adm_stg_cpt_option_sys_twilio_gate_from_number', '', 'digit', '', '', '', 3);
 
+
+--
+-- CATEGORY (HIDDEN): Audit
+--
+INSERT INTO `sys_options_categories`(`type_id`, `name`, `caption`, `hidden`, `order`) VALUES (@iTypeId, 'audit', '_adm_stg_cpt_category_audit', 1, 2);
+SET @iCategoryId = LAST_INSERT_ID();
+
+INSERT INTO `sys_options`(`category_id`, `name`, `caption`, `value`, `type`, `extra`, `check`, `check_error`, `order`) VALUES
+(@iCategoryId, 'sys_audit_enable', '_adm_stg_cpt_option_sys_audit_enable', '', 'checkbox', '', '', '', 1),
+(@iCategoryId, 'sys_audit_max_records', '_adm_stg_cpt_option_sys_audit_max_records', '10000', 'digit', '', '', '', 2),
+(@iCategoryId, 'sys_audit_days_before_expire', '_adm_stg_cpt_option_sys_audit_days_before_expire', '365', 'digit', '', '', '', 3),
+(@iCategoryId, 'sys_audit_acl_levels', '_adm_stg_cpt_option_sys_audit_acl_levels', '7,8', 'digit', 'a:4:{s:6:"module";s:6:"system";s:6:"method";s:15:"get_memberships";s:6:"params";a:0:{}s:5:"class";s:16:"TemplAclServices";}', '', '', 4);
 --
 -- Table structure for table `sys_options_mixes`
 --
@@ -1494,6 +1505,7 @@ CREATE TABLE `sys_audit` (
   `id` int(11) unsigned NOT NULL auto_increment, 
   `added` int(11) NOT NULL, 
   `profile_id` int(10) NOT NULL, 
+  `profile_title` varchar(255) NOT NULL, 
   `content_id` int(10) NOT NULL, 
   `content_title` varchar(255) NOT NULL, 
   `content_module` varchar(32) NOT NULL default '',
@@ -1788,7 +1800,8 @@ INSERT INTO `sys_cron_jobs` (`name`, `time`, `class`, `file`, `service_call`) VA
 ('sys_storage', '* * * * *', 'BxDolCronStorage', 'inc/classes/BxDolCronStorage.php', ''),
 ('sys_transcoder', '* * * * *', 'BxDolCronTranscoder', 'inc/classes/BxDolCronTranscoder.php', ''),
 ('sys_queue_email', '* * * * *', 'BxDolCronQueueEmail', 'inc/classes/BxDolCronQueueEmail.php', ''),
-('sys_queue_push', '* * * * *', 'BxDolCronQueuePush', 'inc/classes/BxDolCronQueuePush.php', '');
+('sys_queue_push', '* * * * *', 'BxDolCronQueuePush', 'inc/classes/BxDolCronQueuePush.php', ''),
+('sys_audit_clean', '* * * * *', 'BxDolCronAudit', 'inc/classes/BxDolCronAudit.php', '');
 
 -- --------------------------------------------------------
 

+ 6 - 23
modules/base/general/classes/BxBaseModGeneralFormsEntryHelper.php

@@ -495,8 +495,8 @@ class BxBaseModGeneralFormsEntryHelper extends BxDolProfileForms
         bx_audit(
             $iContentId, 
             $this->_oModule->getName(), 
-            '_sys_audit_action_detete',  
-            $this->_prepareAuditParams($aContentInfo)
+            '_sys_audit_action_detete_content',  
+            $this->_oModule->_prepareAuditParams($aContentInfo)
         );
         
         return '';
@@ -532,8 +532,8 @@ class BxBaseModGeneralFormsEntryHelper extends BxDolProfileForms
         bx_audit(
             $iContentId, 
             $this->_oModule->getName(), 
-            '_sys_audit_action_edit',  
-            $this->_prepareAuditParams($aContentInfo)
+            '_sys_audit_action_edit_content',  
+            $this->_oModule->_prepareAuditParams($aContentInfo)
         );
         
         return '';
@@ -556,8 +556,8 @@ class BxBaseModGeneralFormsEntryHelper extends BxDolProfileForms
         bx_audit(
             $iContentId, 
             $this->_oModule->getName(), 
-            '_sys_audit_action_add',  
-            $this->_prepareAuditParams($aContentInfo)
+            '_sys_audit_action_add_content',  
+            $this->_oModule->_prepareAuditParams($aContentInfo)
         );
         
         return '';
@@ -587,23 +587,6 @@ class BxBaseModGeneralFormsEntryHelper extends BxDolProfileForms
         
         return $s;
     }
-
-    private function _prepareAuditParams($aContentInfo)
-    {
-        $CNF = &$this->_oModule->_oConfig->CNF;
-        
-        $iContextId = isset($CNF['FIELD_ALLOW_VIEW_TO']) && (!empty($aContentInfo[$CNF['FIELD_ALLOW_VIEW_TO']]) && (int)$aContentInfo[$CNF['FIELD_ALLOW_VIEW_TO']] < 0) ? - $aContentInfo[$CNF['FIELD_ALLOW_VIEW_TO']] : 0;
-        
-        $AuditParams = array(
-            'content_title' => (isset($CNF['FIELD_TITLE']) && isset($aContentInfo[$CNF['FIELD_TITLE']])) ? $aContentInfo[$CNF['FIELD_TITLE']] : '',
-            'context_profile_id' => $iContextId,
-            'content_info_object' =>  isset($CNF['OBJECT_CONTENT_INFO']) ? $CNF['OBJECT_CONTENT_INFO'] : '',
-            'data' => $aContentInfo
-        );
-        if ($iContextId > 0)
-            $AuditParams['context_profile_title'] = BxDolProfile::getInstance($iContextId)->getDisplayName();
-        return $AuditParams;
-    }
     
     protected function prepareResponse($mixedResponse, $bAsJson = false, $sKey = 'msg', $aAdditional = array())
     {

+ 17 - 0
modules/base/general/classes/BxBaseModGeneralGridAdministration.php

@@ -180,6 +180,23 @@ class BxBaseModGeneralGridAdministration extends BxTemplGrid
             $aContentInfo = $this->_oModule->_oDb->getContentInfoById($mixedId);
 
             $this->_oModule->alertAfterEdit($aContentInfo);
+            
+            $iContextId = isset($CNF['FIELD_ALLOW_VIEW_TO']) && (!empty($aContentInfo[$CNF['FIELD_ALLOW_VIEW_TO']]) && (int)$aContentInfo[$CNF['FIELD_ALLOW_VIEW_TO']] < 0) ? - $aContentInfo[$CNF['FIELD_ALLOW_VIEW_TO']] : 0;
+            $AuditParams = array(
+                'content_title' => (isset($CNF['FIELD_TITLE']) && isset($aContentInfo[$CNF['FIELD_TITLE']])) ? $aContentInfo[$CNF['FIELD_TITLE']] : '',
+                'context_profile_id' => $iContextId,
+                'content_info_object' =>  isset($CNF['OBJECT_CONTENT_INFO']) ? $CNF['OBJECT_CONTENT_INFO'] : '',
+                'data' => $aContentInfo
+            );
+            if ($iContextId > 0)
+                $AuditParams['context_profile_title'] = BxDolProfile::getInstance($iContextId)->getDisplayName();
+            
+            bx_audit(
+                $mixedId, 
+                $this->_oModule->getName(), 
+                ($isChecked ? '_sys_audit_action_content_enabled': '_sys_audit_action_content_disabled'), 
+                $AuditParams
+            );
         }
 
         return $mixedResult;

+ 20 - 0
modules/base/general/classes/BxBaseModGeneralModule.php

@@ -1928,6 +1928,26 @@ class BxBaseModGeneralModule extends BxDolModule
 		echoJson($aResponse);
 		exit;
     }
+    
+    protected function _prepareAuditParams($aContentInfo, $bIsSaveData = true, $aOverrideAuditParams  = array())
+    {
+        $CNF = &$this->_oConfig->CNF;
+        
+        $iContextId = isset($CNF['FIELD_ALLOW_VIEW_TO']) && (!empty($aContentInfo[$CNF['FIELD_ALLOW_VIEW_TO']]) && (int)$aContentInfo[$CNF['FIELD_ALLOW_VIEW_TO']] < 0) ? - $aContentInfo[$CNF['FIELD_ALLOW_VIEW_TO']] : 0;
+        
+        $AuditParams = array(
+            'content_title' => (isset($CNF['FIELD_TITLE']) && isset($aContentInfo[$CNF['FIELD_TITLE']])) ? $aContentInfo[$CNF['FIELD_TITLE']] : '',
+            'context_profile_id' => $iContextId,
+            'content_info_object' =>  isset($CNF['OBJECT_CONTENT_INFO']) ? $CNF['OBJECT_CONTENT_INFO'] : '',
+            'data' => ($bIsSaveData ? $aContentInfo : array())
+        );
+        if ($iContextId > 0)
+            $AuditParams['context_profile_title'] = BxDolProfile::getInstance($iContextId)->getDisplayName();
+        
+        $AuditParams = array_merge($AuditParams, $aOverrideAuditParams);
+        
+        return $AuditParams;
+    }
 }
 
 /** @} */

+ 4 - 0
modules/base/groups/classes/BxBaseModGroupsDb.php

@@ -47,6 +47,8 @@ class BxBaseModGroupsDb extends BxBaseModProfileDb
         if ($oModule && method_exists($oModule, 'onFanAddedToAdmins'))
             $oModule->onFanAddedToAdmins($iGroupProfileId, $iFanId);
 
+        $oModule->doAudit($iGroupProfileId, $iFanId, '_sys_audit_action_group_to_admins');
+        
         return true;
     }
 
@@ -67,6 +69,8 @@ class BxBaseModGroupsDb extends BxBaseModProfileDb
         if ($oModule && method_exists($oModule, 'onFanRemovedFromAdmins'))
             $oModule->onFanRemovedFromAdmins($iGroupProfileId, $iFanId);
         
+        $oModule->doAudit($iGroupProfileId, $iFanId, '_sys_audit_action_group_from_admins');
+        
         return true;
     }
 

+ 29 - 1
modules/base/groups/classes/BxBaseModGroupsModule.php

@@ -282,6 +282,9 @@ class BxBaseModGroupsModule extends BxBaseModProfileModule
             	'group_profile' => $iGroupProfileId, 
             	'profile' => $iProfileId,
             ));
+            
+            $this->doAudit($iGroupProfileId, $iInitiatorId, '_sys_audit_action_group_join_request_accepted');
+            
             return false;
         }
 
@@ -653,7 +656,32 @@ class BxBaseModGroupsModule extends BxBaseModProfileModule
     {
         return parent::checkAllowedSubscribeAdd ($aDataEntry, $isPerformAction);
     }
-
+    
+    public function doAudit($iGroupProfileId, $iFanId, $sAction)
+    {
+        $oProfile = BxDolProfile::getInstance($iFanId);
+        
+        $iContentId = $oProfile->getContentId();
+        $sModule = $oProfile->getModule();
+        $oModule = BxDolModule::getInstance($sModule);
+        $CNF = $oModule->_oConfig->CNF;
+        
+        $aContentInfo = BxDolRequest::serviceExists($sModule, 'get_all') ? BxDolService::call($sModule, 'get_all', array(array('type' => 'id', 'id' => $iContentId))) : array();
+        
+        $AuditParams = array(
+            'content_title' => (isset($CNF['FIELD_TITLE']) && isset($aContentInfo[$CNF['FIELD_TITLE']])) ? $aContentInfo[$CNF['FIELD_TITLE']] : '',
+            'context_profile_id' => $iGroupProfileId,
+            'context_profile_title' => BxDolProfile::getInstance($iGroupProfileId)->getDisplayName()
+        );
+        
+        bx_audit(
+            $iContentId, 
+            $sModule, 
+            $sAction,  
+            $AuditParams
+        );
+    }
+    
     protected function _checkAllowedConnect (&$aDataEntry, $isPerformAction, $sObjConnection, $isMutual, $isInvertResult, $isSwap = false)
     {
         $sResult = $this->checkAllowedView($aDataEntry);

+ 15 - 2
modules/boonex/accounts/classes/BxAccntGridAdministration.php

@@ -132,6 +132,8 @@ class BxAccntGridAdministration extends BxBaseModProfileGridAdministration
                 bx_alert('account', 'edited', $aAccount['id'], BxDolAccount::getInstance()->id(), array('display' => $CNF['OBJECT_FORM_ACCOUNT_DISPLAY_SETTINGS_EMAIL']));
 
                 $aRes = array('grid' => $this->getCode(false), 'blink' => $iId);
+                
+                $oAccount->doAudit($iId, '_sys_audit_action_account_email_changed', array('old_email' => $oAccount->getEmail(), 'new_email' => $sEmail));
             }
             else
                 $aRes = array('msg' => _t('_sys_txt_error_account_update'));
@@ -167,7 +169,7 @@ class BxAccntGridAdministration extends BxBaseModProfileGridAdministration
         foreach($aIds as $iId)
 			if($oAccount->sendConfirmationEmail($iId)) {
 				$aIdsAffected[] = $iId;
-        		$iAffected++;
+        		$iAffected++;  
 			}
 
 		echoJson($iAffected ? array('grid' => $this->getCode(false), 'blink' => $aIdsAffected) : array('msg' => _t($CNF['T']['grid_action_err_perform'])));
@@ -204,6 +206,8 @@ class BxAccntGridAdministration extends BxBaseModProfileGridAdministration
             ));
 
             $aRes = array('popup' => BxTemplStudioFunctions::getInstance()->popupBox($sPopupId, $sPopupTitle, $sPopupContent));
+            
+            $oAccount->doAudit($iId, '_sys_audit_action_account_reset_password');
         }
         else 
             $aRes = array('msg' => _t('_bx_accnt_grid_action_err_perform'));
@@ -226,6 +230,8 @@ class BxAccntGridAdministration extends BxBaseModProfileGridAdministration
 			if ($oAccount->isLocked()){
 				$oAccountQuery->unlockAccount($iId);
 			}
+            
+            $oAccount->doAudit($iId, '_sys_audit_action_account_unlock');
 		}
 		$aRes = array('grid' => $this->getCode(false), 'blink' => $aIds);
         return echoJson($aRes);
@@ -257,6 +263,9 @@ class BxAccntGridAdministration extends BxBaseModProfileGridAdministration
 			if($this->_oModule->_oDb->updateAccount(array('role' => $iRole), array('id' => $iId))) {
 				$aIdsAffected[] = $iId;
         		$iAffected++;
+                
+                $oAccount = BxDolAccount::getInstance($iId);
+                $oAccount->doAudit($iId, '_sys_audit_action_account_change_role_to_' . $iRole);
 			}
 
 		echoJson($iAffected ? array('grid' => $this->getCode(false), 'blink' => $aIdsAffected) : array('msg' => _t($CNF['T']['grid_action_err_perform'])));
@@ -271,13 +280,15 @@ class BxAccntGridAdministration extends BxBaseModProfileGridAdministration
             echoJson(array());
             return;
         }
-
         $iAffected = 0;
         $aIdsAffected = array();
         foreach($aIds as $iId)
         	if($this->_enable($iId, $isChecked)) {
         		$aIdsAffected[] = $iId;
         		$iAffected++;
+                
+                $oAccount = BxDolAccount::getInstance($iId);
+                $oAccount->doAudit($iId, '_sys_audit_action_account_' . $isChecked ? 'activated' : 'suspended');
         	}
 
         echoJson($iAffected ? array('grid' => $this->getCode(false), 'blink' => $aIdsAffected) : array('msg' => _t($CNF['T']['grid_action_err_perform'])));
@@ -368,6 +379,8 @@ class BxAccntGridAdministration extends BxBaseModProfileGridAdministration
     {
     	return BxDolAccount::getInstance($iId)->delete(isset($aParams['with_content']) && $aParams['with_content'] === true);
     }
+    
+    
 
     protected function _addJsCss()
     {

+ 43 - 4
modules/boonex/english/data/langs/system/en.xml

@@ -1282,6 +1282,7 @@
 	<string name="_adm_scs_operation_done"><![CDATA[]]></string>
 	<string name="_adm_stg_cpt_category_account"><![CDATA[Account]]></string>
 	<string name="_adm_stg_cpt_category_acl"><![CDATA[ACL]]></string>
+  <string name="_adm_stg_cpt_category_audit"><![CDATA[Audit]]></string>
 	<string name="_adm_stg_cpt_category_notifications"><![CDATA[Notifications]]></string>
 	<string name="_adm_stg_cpt_category_notifications_push"><![CDATA[Push Notifications]]></string>
 	<string name="_adm_stg_cpt_category_cache"><![CDATA[Cache]]></string>
@@ -1333,6 +1334,10 @@
 	<string name="_adm_stg_cpt_option_sys_acl_expire_notification_days"><![CDATA[Number of days before membership expiration to notify members (-1 = after expiration)]]></string>
 	<string name="_adm_stg_cpt_option_sys_acl_expire_notify_once"><![CDATA[Notify members about membership expiration only once (every day otherwise)]]></string>
 	<string name="_adm_stg_cpt_option_sys_add_nofollow"><![CDATA[Add "nofollow" attribute for external links]]></string>
+  <string name="_adm_stg_cpt_option_sys_audit_enable"><![CDATA[Enable]]></string>
+  <string name="_adm_stg_cpt_option_sys_audit_max_records"><![CDATA[Number of log records]]></string>
+  <string name="_adm_stg_cpt_option_sys_audit_days_before_expire"><![CDATA[Delete logs older than (days)]]></string>
+  <string name="_adm_stg_cpt_option_sys_audit_acl_levels"><![CDATA[Enable for levels]]></string>
 	<string name="_adm_stg_cpt_option_sys_autoupdate_force_modified_files"><![CDATA[Force auto-update, even if some files were modified]]></string>
 	<string name="_adm_stg_cpt_option_sys_autoupdate"><![CDATA[Enable auto-update]]></string>
 	<string name="_adm_stg_cpt_option_sys_cache_memcache_host"><![CDATA[Memcached server host]]></string>
@@ -1714,11 +1719,45 @@
 	<string name="_sys_acl_expire"><![CDATA[Expire: ]]></string>
 	<string name="_sys_acl_expire_never"><![CDATA[never]]></string>
 
-  <string name="_sys_audit_action_edit"><![CDATA[Edit]]></string>
-  <string name="_sys_audit_action_add"><![CDATA[Add]]></string>
-  <string name="_sys_audit_action_delete"><![CDATA[Delete]]></string>
+  <string name="_sys_audit_action_edit_content"><![CDATA[Content edited]]></string>
+  <string name="_sys_audit_action_add_content"><![CDATA[Content added]]></string>
+  <string name="_sys_audit_action_detete_content"><![CDATA[Content removed]]></string>
+  <string name="_sys_audit_action_edit_comment"><![CDATA[Comment edited]]></string>
+  <string name="_sys_audit_action_add_comment"><![CDATA[Comment added]]></string>
+  <string name="_sys_audit_action_delete_comment"><![CDATA[Comment removed]]></string>
+  <string name="_sys_audit_action_feature"><![CDATA[Featured]]></string>
+  <string name="_sys_audit_action_unfeature"><![CDATA[Unfeatured]]></string>
+  <string name="_sys_audit_action_group_to_admins"><![CDATA[Added to group admins]]></string>
+  <string name="_sys_audit_action_group_from_admins"><![CDATA[Removed from group admins]]></string>
+  <string name="_sys_audit_action_group_join_request_accepted"><![CDATA[Join requestaccepted]]></string>
+  <string name="_sys_audit_action_account_change_role_to_3"><![CDATA[Made operator]]></string>
+  <string name="_sys_audit_action_account_change_role_to_1"><![CDATA[Unmade operator]]></string>
+  <string name="_sys_audit_action_account_unlock"><![CDATA[Unlocked]]></string>
+  <string name="_sys_audit_action_account_reset_password"><![CDATA[Password reseted]]></string>
+  <string name="_sys_audit_action_account_resend_confirmation_email"><![CDATA[Confirmation email re-sended]]></string>
+  <string name="_sys_audit_action_account_deleted_with_content"><![CDATA[Removed with content]]></string>
+  <string name="_sys_audit_action_account_deleted"><![CDATA[Removed]]></string>
+  <string name="_sys_audit_action_account_email_changed"><![CDATA[Email changed]]></string>
+  <string name="_sys_audit_action_account_activated"><![CDATA[Activated]]></string>
+  <string name="_sys_audit_action_account_suspended"><![CDATA[Suspended]]></string>
+  <string name="_sys_audit_action_content_enabled"><![CDATA[Enabled]]></string>
+  <string name="_sys_audit_action_content_disabled"><![CDATA[Disabled]]></string>
+  <string name="_sys_audit_action_set_membership"><![CDATA[Membership set]]></string>
+  <string name="_sys_audit_action_set_status_approve"><![CDATA[Approved]]></string>
+  <string name="_sys_audit_action_set_status_active"><![CDATA[Activated]]></string>
+  <string name="_sys_audit_action_set_status_disapprove"><![CDATA[Disapproved]]></string>
+  <string name="_sys_audit_action_set_status_suspended"><![CDATA[Suspended]]></string>
+  <string name="_sys_audit_action_report"><![CDATA[Reported]]></string>
+  <string name="_sys_audit_action_lock"><![CDATA[Locked]]></string>
+  <string name="_sys_audit_action_unlock"><![CDATA[Unlocked]]></string>
+  <string name="_sys_audit_action_stick"><![CDATA[Sticked]]></string>
+  <string name="_sys_audit_action_unstick"><![CDATA[Unsticked]]></string>
+  <string name="_sys_audit_action_promote"><![CDATA[Promoted]]></string>
+  <string name="_sys_audit_action_unpromote"><![CDATA[Unpromoted]]></string>
+  <string name="_sys_audit_action_unpromote"><![CDATA[Unpromoted]]></string>
   
-	<string name="_sys_add_friend"><![CDATA[Add friend]]></string>
+
+  <string name="_sys_add_friend"><![CDATA[Add friend]]></string>
         <string name="_sys_add_relation"><![CDATA[Add relationship]]></string>
 	<string name="_sys_adm_installed"><![CDATA[Installed]]></string>
 	<string name="_sys_admin_apply"><![CDATA[Apply]]></string>

+ 7 - 0
modules/boonex/forum/classes/BxForumModule.php

@@ -57,6 +57,13 @@ class BxForumModule extends BxBaseModTextModule
         if($sResult !== CHECK_ACTION_RESULT_ALLOWED)
         	return echoJson(array('code' => 2, 'message' => $sResult));
 
+        bx_audit(
+            $iContentId, 
+            $this->getName(), 
+            '_sys_audit_action_' . $sAction,  
+            $this->_prepareAuditParams($aContentInfo, false)
+        );
+        
         if(!$this->_oDb->updateStatus($sAction, $aContentInfo))
         	return echoJson(array('code' => 3, 'message' => _t('_error occured')));
 

+ 14 - 0
modules/boonex/timeline/classes/BxTimelineModule.php

@@ -161,6 +161,13 @@ class BxTimelineModule extends BxBaseModNotificationsModule implements iBxDolCon
     	if(!$this->_oDb->updateEvent(array('sticked' => $aEvent['sticked']), array('id' => $iId)))
             return echoJson(array('code' => 3));
 
+        bx_audit(
+            $iId, 
+            $this->getName(), 
+            '_sys_audit_action_' . ((int)$aEvent['sticked'] == 0 ? 'stick' : 'unstick'),  
+            $this->_prepareAuditParams($aEvent, false)
+        );
+        
     	echoJson(array(
             'code' => 0,
             'id' => $iId,
@@ -190,6 +197,13 @@ class BxTimelineModule extends BxBaseModNotificationsModule implements iBxDolCon
             'object_id' => $aEvent['object_id'],
             'object_author_id' => $this->_oConfig->isSystem($aEvent['type'], $aEvent['action']) ? $aEvent['owner_id'] : $aEvent['object_id']
         ));
+        
+        bx_audit(
+            $iId, 
+            $this->getName(), 
+            '_sys_audit_action_' . ((int)$aEvent['promoted'] == 0 ? 'promote' : 'unpromote'),  
+            $this->_prepareAuditParams($aEvent, false)
+        );
 
         echoJson(array(
             'code' => 0, 

+ 1 - 0
studio/classes/BxDolStudioAudit.php

@@ -8,6 +8,7 @@
  */
 
 define('BX_DOL_STUDIO_AUD_TYPE_GENERAL', 'general');
+define('BX_DOL_STUDIO_AUD_TYPE_SETTINGS', 'settings');
 
 define('BX_DOL_STUDIO_AUD_TYPE_DEFAULT', BX_DOL_STUDIO_AUD_TYPE_GENERAL);
 

+ 1 - 0
studio/classes/BxDolStudioSettings.php

@@ -18,6 +18,7 @@ define('BX_DOL_STUDIO_STG_GROUP_TEMPLATES', 'templates');
 define('BX_DOL_STUDIO_STG_CATEGORY_SYSTEM', 'system');
 define('BX_DOL_STUDIO_STG_CATEGORY_LANGUAGES', 'languages');
 define('BX_DOL_STUDIO_STG_CATEGORY_TEMPLATES', 'templates');
+define('BX_DOL_STUDIO_STG_CATEGORY_AUDIT', 'audit');
 
 define('BX_DOL_STUDIO_STG_MIX_SYSTEM', 'system');
 define('BX_DOL_STUDIO_STG_MIX_DEFAULT', BX_DOL_STUDIO_STG_MIX_SYSTEM);

+ 12 - 1
studio/template/scripts/BxBaseStudioAudit.php

@@ -21,7 +21,8 @@ class BxBaseStudioAudit extends BxDolStudioAudit
         $this->sSubpageUrl = BX_DOL_URL_STUDIO . 'audit.php?page=';
 
 		$this->aMenuItems = array(
-            BX_DOL_STUDIO_AUD_TYPE_GENERAL => array('icon' => 'search')
+            BX_DOL_STUDIO_AUD_TYPE_GENERAL => array('icon' => 'search'),
+            BX_DOL_STUDIO_AUD_TYPE_SETTINGS => array('icon' => 'cogs'),
 	    );
 
 		$this->aGridObjects = array(
@@ -78,6 +79,16 @@ class BxBaseStudioAudit extends BxDolStudioAudit
     {
         return $this->getGrid($this->aGridObjects['audit']);
     }
+    
+    protected function getSettings()
+    {
+       
+        $oPage = new BxTemplStudioSettings(BX_DOL_STUDIO_STG_TYPE_SYSTEM, BX_DOL_STUDIO_STG_CATEGORY_AUDIT);
+        return BxDolStudioTemplate::getInstance()->parseHtmlByName('audit.html', array(
+            'content' => $oPage->getPageCode(),
+        	'js_content' => ''
+        ));
+    }
 
     protected function getGrid($sObjectName)
     {

+ 31 - 4
studio/template/scripts/BxBaseStudioAuditGrid.php

@@ -40,7 +40,7 @@ class BxBaseStudioAuditGrid extends BxDolStudioAuditGrid
         if ($aRow['content_id'] > 0 && $aRow['content_info_object'] != ''){
             $oContentInfo = BxDolContentInfo::getObjectInstance($aRow['content_info_object']);
             if ($oContentInfo){
-    	        $sTitle = $oContentInfo->getContentTitle($aRow['content_id']);
+    	        $sTitle = bx_process_output($oContentInfo->getContentTitle($aRow['content_id']));
                 if ($sTitle != ''){
                     $mixedValue =  $this->_oTemplate->parseHtmlByName('account_link.html', array(
                         'href' => $oContentInfo->getContentLink($aRow['content_id']),
@@ -52,7 +52,7 @@ class BxBaseStudioAuditGrid extends BxDolStudioAuditGrid
             }
         }
         if ($mixedValue == ''){
-            $mixedValue = $aRow['content_title'];
+            $mixedValue = bx_process_output($aRow['content_title']);
         }
         return parent::_getCellDefault($mixedValue, $sKey, $aField, $aRow);
     }
@@ -83,9 +83,12 @@ class BxBaseStudioAuditGrid extends BxDolStudioAuditGrid
     protected function _getCellModule ($mixedValue, $sKey, $aField, $aRow)
     {
         $oModule = bxDolModule::getInstance($aRow['content_module']);
-        if($oModule instanceof iBxDolContentInfoService){
+        if($oModule && $oModule instanceof iBxDolContentInfoService){
             $mixedValue = $oModule->_aModule['title'];
         }
+        else{
+            $mixedValue = $aRow['content_module'];
+        }
         return parent::_getCellDefault($mixedValue, $sKey, $aField, $aRow);
     }
     
@@ -104,7 +107,7 @@ class BxBaseStudioAuditGrid extends BxDolStudioAuditGrid
                 ));
             }
             else{
-                $mixedValue = 'deleted';
+                $mixedValue = $aRow['profile_title'];
             }
         }
         else{
@@ -138,6 +141,30 @@ class BxBaseStudioAuditGrid extends BxDolStudioAuditGrid
         return  $sContent;
     }
     
+    protected function _getDataSql($sFilter, $sOrderField, $sOrderDir, $iStart, $iPerPage)
+    {
+        $sFilterContent = bx_get('content_id');
+        if(!empty($sFilter2)) {
+            $sFilterContent = bx_process_input($sFilterContent);
+            $this->_aOptions['source'] .= " AND `content_id` = " .  $sFilterContent . 'AND `content_module` = ' . $this->sModule;
+        }
+        
+        $sFilterContext = bx_get('context_id');
+        if(!empty($sFilterContext)) {
+            $sFilterContext = bx_process_input($sFilterContext);
+            $this->_aOptions['source'] .= " AND `context_profile_id` = " .  $sFilterContext;
+        }
+        
+        $sPrifile = bx_get('profile_id');
+        if(!empty($sPrifile)) {
+            $sPrifile = bx_process_input($sPrifile);
+            $this->_aOptions['source'] .= " AND `profile_id` = " .  $sPrifile;
+        }
+
+
+        return parent::_getDataSql($sFilter, $sOrderField, $sOrderDir, $iStart, $iPerPage);
+    }
+    
     function getJsObject()
     {
         return 'oBxDolStudioFormsAudit';

+ 24 - 0
template/scripts/BxBaseReport.php

@@ -280,6 +280,13 @@ class BxBaseReport extends BxDolReport
 		
 		        $oZ = new BxDolAlerts('report', 'do', $iId, $iAuthorId, array('object_system' => $this->_sSystem, 'object_id' => $iObjectId, 'object_author_id' => $iObjectAuthorId, 'type' => $sType, 'text' => $sText));
 		        $oZ->alert();
+                
+                bx_audit(
+                    $iObjectId, 
+                    $this->_sSystem, 
+                    '_sys_audit_action_report',  
+                    $this->_prepareAuditParams($iObjectId, array('type' => $sType, 'text' => $sText))
+                );
 
 		        $aReport = $this->_oQuery->getReport($iObjectId);
 		        return array(
@@ -340,6 +347,23 @@ class BxBaseReport extends BxDolReport
             'bx_repeat:list' => $aTmplReports
         ));
     }
+    
+    private function _prepareAuditParams($iObjectId, $aData)
+    {
+        $sModule = $this->_sSystem;
+        $oModule = BxDolModule::getInstance($sModule);
+        $CNF = $oModule->_oConfig->CNF;
+
+        $aContentInfo = BxDolRequest::serviceExists($sModule, 'get_all') ? BxDolService::call($sModule, 'get_all', array(array('type' => 'id', 'id' => $iObjectId))) : array();
+        
+        $AuditParams = array(
+            'content_title' => isset($CNF['FIELD_TITLE'])  ? $aContentInfo[$CNF['FIELD_TITLE']] : '',
+            'content_info_object' =>  isset($CNF['OBJECT_CONTENT_INFO']) ? $CNF['OBJECT_CONTENT_INFO'] : '',
+            'data' => $aData 
+        );
+        
+        return $AuditParams;
+    }
 }
 
 /** @} */