瀏覽代碼

Ticket #194: Report engine and related changes in core.

AntonLV 10 年之前
父節點
當前提交
523f16323f

+ 0 - 3
inc/classes/BxDolCronPruning.php

@@ -54,9 +54,6 @@ class BxDolCronPruning extends BxDolCron
         $oKey = BxDolKey::getInstance();
         $iDeletedKeys = $oKey ? $oKey->prune() : 0;
 
-        // clean old votes
-        $iDeletedVotes = BxDolVote::maintenance();
-
         echo _t('_sys_pruning_db', $iDeleteMemLevels, $iSessions, $iDeletedViews, $iDeletedVotes, $iDeletedKeys, $iDeletedExpiredTokens, $iDeletedTranscodedImages);
     }
 

+ 32 - 27
inc/classes/BxDolObject.php

@@ -13,11 +13,13 @@
  */
 class BxDolObject extends BxDol
 {
+	protected $_oQuery = null;
+
     protected $_iId = 0; ///< item id the action to be performed with
     protected $_sSystem = ''; ///< current system name
     protected $_aSystem = array(); ///< current system array
 
-    protected $_oQuery = null;
+    protected $_aMarkers = array ();
 
     public function __construct($sSystem, $iId, $iInit = 1)
     {
@@ -37,30 +39,6 @@ class BxDolObject extends BxDol
             $this->init($iId);
     }
 
-    /**
-     * it is called on cron every day or similar period to clean old votes
-     */
-    public static function maintenance()
-    {
-        $iResult = 0;
-        $oDb = BxDolDb::getInstance();
-
-        $aSystems = self::getSystems();
-        foreach($aSystems as $aSystem) {
-            if(!$aSystem['is_on'])
-                continue;
-
-            $sQuery = $oDb->prepare("DELETE FROM `{$aSystem['table_track']}` WHERE `date` < (UNIX_TIMESTAMP() - ?)", BX_DOL_VOTE_OLD_VOTES);
-            $iDeleted = (int)$oDb->query($sQuery);
-            if($iDeleted > 0)
-                $oDb->query("OPTIMIZE TABLE `{$aSystem['table_track']}`");
-
-            $iResult += $iDeleted;
-        }
-
-        return $iResult;
-    }
-
     public function init($iId)
     {
         if(!$this->isEnabled())
@@ -69,6 +47,11 @@ class BxDolObject extends BxDol
         if(empty($this->_iId) && $iId)
             $this->setId($iId);
 
+		$this->addMarkers(array(
+            'object_id' => $this->getId(),
+            'user_id' => $this->_getAuthorId()
+        ));
+
         return true;
     }
 
@@ -116,6 +99,15 @@ class BxDolObject extends BxDol
         return $this->_oQuery->getSqlParts($sMainTable, $sMainField);
     }
 
+    public function addMarkers($aMarkers)
+    {
+        if(empty($aMarkers) || !is_array($aMarkers))
+			return false;
+
+        $this->_aMarkers = array_merge($this->_aMarkers, $aMarkers);
+        return true;
+    }
+
 	/**
      * Permissions functions
      */
@@ -173,9 +165,12 @@ class BxDolObject extends BxDol
 
     protected function _getAuthorObject($iAuthorId = 0)
     {
+    	if($iAuthorId == 0)
+    		return BxDolProfileUndefined::getInstance();
+
         $oProfile = BxDolProfile::getInstance($iAuthorId);
-        if (!$oProfile)
-            $oProfile = BxDolProfileUndefined::getInstance();
+        if(!$oProfile)
+			$oProfile = BxDolProfileUndefined::getInstance();
 
         return $oProfile;
     }
@@ -191,6 +186,16 @@ class BxDolObject extends BxDol
 
         return $this->_oQuery->updateTriggerTable($iId);
     }
+
+    /**
+     * Replace provided markers in a string
+     * @param $mixed string or array to replace markers in
+     * @return string where all occured markers are replaced
+     */
+    protected function _replaceMarkers ($mixed)
+    {
+        return bx_replace_markers($mixed, $this->_aMarkers);
+    }
 }
 
 /** @} */

+ 4 - 1
inc/classes/BxDolProfileUndefined.php

@@ -79,7 +79,10 @@ class BxDolProfileUndefined extends BxDol implements iBxDolSingleton, iBxDolProf
      */
     public function getUnit()
     {
-        return '<div>' . $this->getDisplayName() . '</div>';
+		return BxDolTemplate::getInstance()->parseHtmlByName('profile_unit.html', array(
+        	'thumb_url' => $this->getThumb(),
+        	'title' => $this->getDisplayName()
+        ));
     }
 
     /**

+ 37 - 32
inc/classes/BxDolReport.php

@@ -27,55 +27,48 @@ define('BX_DOL_REPORT_USAGE_DEFAULT', BX_DOL_REPORT_USAGE_BLOCK);
  * - BxBaseReport - report base representation
  * - BxTemplReport - custom template representation
  *
- * AJAX vote for any content. Stars and Plus based representations are supported.
- *
- * To add vote section to your feature you need to add a record to 'sys_objects_vote' table:
- *
- * - ID - autoincremented id for internal usage
- * - Name - your unique module name, with vendor prefix, lowercase and spaces are underscored
- * - TableMain - table name where summary votigs are stored
- * - TableTrack - table name where each vote is stored
- * - PostTimeout - number of seconds to not allow duplicate vote
- * - MinValue - min vote value, 1 by default
- * - MaxValue - max vote value, 5 by default
- * - IsUndo - is Undo enabled for Plus based votes
- * - IsOn - is this vote object enabled
- * - TriggerTable - table to be updated upon each vote
- * - TriggerFieldId - TriggerTable table field with unique record id, primary key
- * - TriggerFieldRate - TriggerTable table field with average rate
- * - TriggerFieldRateCount - TriggerTable table field with votes count
- * - ClassName - your custom class name, if you overrride default class
- * - ClassFile - your custom class path
+ * AJAX report for any content.
+ *
+ * To add report section to your feature you need to add a record to 'sys_objects_report' table:
+ *
+ * - id - autoincremented id for internal usage
+ * - name - your unique module name, with vendor prefix, lowercase and spaces are underscored
+ * - table_main - table name where summary reports are stored
+ * - table_track - table name where each report is stored
+ * - is_on - is this report object enabled
+ * - base_url - base URL for reported object
+ * - trigger_table - table to be updated upon each report
+ * - trigger_field_id - trigger_table table field with unique record id, primary key
+ * - trigger_field_author - trigger_table table field with author
+ * - trigger_field_count - trigger_table table field with reports count
+ * - class_name - your custom class name, if you overrride default class
+ * - class_file - your custom class path
  *
  * You can refer to BoonEx modules for sample record in this table.
  *
  *
  *
  * @section example Example of usage:
- * To get Star based vote you need to have different values for MinValue and MaxValue (for example 1 and 5)
- * and IsUndo should be equal to 0. To get Plus(Like) based vote you need to have equal values
- * for MinValue and MaxValue (for example 1) and IsUndo should be equal to 1. After filling the other
- * paramenters in the table you can show vote in any place, using the following code:
+ * You can show report in any place, using the following code:
  * @code
- * $o = BxDolVote::getObjectInstance('system object name', $iYourEntryId);
- * if (!$o->isEnabled()) return '';
- *     echo $o->getElementBlock();
+ * $o = BxDolReport::getObjectInstance('system object name', $iYourEntryId);
+ * if (!$o->isEnabled()) 
+ *     return '';
+ * echo $o->getElementBlock();
  * @endcode
  *
  *
  * @section acl Memberships/ACL:
- * - vote
- *
+ * - report
+ * - report view
  *
  *
  * @section alerts Alerts:
  * Alerts type/unit - every module has own type/unit, it equals to ObjectName.
  * The following alerts are rised:
  *
- * - rate - comment was posted
- *      - $iObjectId - entry id
- *      - $iSenderId - rater user id
- *      - $aExtra['rate'] - rate
+ * - type: 'object name', action: doReport
+ * - type: report, action: do
  *
  */
 
@@ -83,6 +76,8 @@ class BxDolReport extends BxDolObject
 {
 	protected $_oTemplate;
 
+	protected $_sBaseUrl;
+
 	protected $_sFormObject;
     protected $_sFormDisplayPost;
 
@@ -101,6 +96,10 @@ class BxDolReport extends BxDolObject
         else
             $this->_oTemplate = BxDolTemplate::getInstance();
 
+		$this->_sBaseUrl = BxDolPermalinks::getInstance()->permalink($this->_aSystem['base_url']);
+        if(get_mb_substr($this->_sBaseUrl, 0, 4) != 'http')
+            $this->_sBaseUrl = BX_DOL_URL_ROOT . $this->_sBaseUrl;
+
 		$this->_sFormObject = 'sys_report';
 		$this->_sFormDisplayPost = 'sys_report_post';
 
@@ -144,6 +143,7 @@ class BxDolReport extends BxDolObject
                     `table_main` AS `table_main`,
                     `table_track` AS `table_track`,
                     `is_on` AS `is_on`,
+                    `base_url` AS `base_url`,
                     `trigger_table` AS `trigger_table`,
                     `trigger_field_id` AS `trigger_field_id`,
                     `trigger_field_author` AS `trigger_field_author`,
@@ -158,6 +158,11 @@ class BxDolReport extends BxDolObject
     /**
      * Interface functions for outer usage
      */
+	public function getBaseUrl()
+    {
+        return $this->_replaceMarkers($this->_sBaseUrl);
+    }
+
     public function getStatCounter()
     {
         $aReport = $this->_oQuery->getReport($this->getId());

+ 9 - 1
inc/classes/BxDolReportQuery.php

@@ -29,9 +29,17 @@ class BxDolReportQuery extends BxDolObjectQuery
         return $aResult;
     }
 
+	public function isPerformed($iObjectId, $iAuthorId)
+    {
+    	/*
+    	 * 'false' is returned everytime to allow multiple reports for everybody.
+    	 */
+        return false;
+    }
+
 	public function getPerformedBy($iObjectId)
     {
-        $sQuery = $this->prepare("SELECT `author_id`, `type`, `text` FROM `{$this->_sTableTrack}` WHERE `object_id`=?", $iObjectId);
+        $sQuery = $this->prepare("SELECT `author_id`, `type`, `text` FROM `{$this->_sTableTrack}` WHERE `object_id`=? ORDER BY `date` DESC", $iObjectId);
         return $this->getAll($sQuery);
     }
 

+ 24 - 0
inc/classes/BxDolView.php

@@ -111,6 +111,30 @@ class BxDolView extends BxDolObject
         return $GLOBALS['bx_dol_view_systems'];
     }
 
+    /**
+     * it is called on cron every day or similar period to clean old votes
+     */
+    public static function maintenance()
+    {
+        $iResult = 0;
+        $oDb = BxDolDb::getInstance();
+
+        $aSystems = self::getSystems();
+        foreach($aSystems as $aSystem) {
+            if(!$aSystem['is_on'])
+                continue;
+
+            $sQuery = $oDb->prepare("DELETE FROM `{$aSystem['table_track']}` WHERE `date` < (UNIX_TIMESTAMP() - ?)", BX_DOL_VIEW_OLD_VIEWS);
+            $iDeleted = (int)$oDb->query($sQuery);
+            if($iDeleted > 0)
+                $oDb->query("OPTIMIZE TABLE `{$aSystem['table_track']}`");
+
+            $iResult += $iDeleted;
+        }
+
+        return $iResult;
+    }
+
     function doView()
     {
         if(!$this->isEnabled())

+ 0 - 2
inc/classes/BxDolVote.php

@@ -9,8 +9,6 @@
 
 bx_import('BxDolAcl');
 
-define('BX_DOL_VOTE_OLD_VOTES', 365 * 86400); ///< votes older than this number of seconds will be deleted automatically
-
 define('BX_DOL_VOTE_TYPE_STARS', 'stars');
 define('BX_DOL_VOTE_TYPE_LIKES', 'likes');
 

+ 2 - 0
install/sql/system.sql

@@ -149,6 +149,7 @@ INSERT INTO `sys_email_templates` (`Module`, `NameSystem`, `Name`, `Subject`, `B
 ('system', '_sys_et_txt_name_system_mem_expiration', 't_MemExpiration', '_sys_et_txt_subject_mem_expiration', '_sys_et_txt_body_mem_expiration'),
 ('system', '_sys_et_txt_name_system_mem_changed', 't_MemChanged', '_sys_et_txt_subject_mem_changed', '_sys_et_txt_body_mem_changed'),
 ('system', '_sys_et_txt_name_system_comment_replied', 't_CommentReplied', '_sys_et_txt_subject_comment_replied', '_sys_et_txt_body_comment_replied'),
+('system', '_sys_et_txt_name_system_reported', 't_Reported', '_sys_et_txt_subject_system_reported', '_sys_et_txt_body_system_reported'),
 ('system', '_sys_et_txt_name_system_delayed_module_uninstall', 't_DelayedModuleUninstall', '_sys_et_txt_subject_delayed_module_uninstall', '_sys_et_txt_body_delayed_module_uninstall'),
 ('system', '_sys_et_txt_name_system_pruning', 't_Pruning', '_sys_et_txt_subject_pruning', '_sys_et_txt_body_pruning'),
 ('system', '_sys_et_txt_name_profile_change_status_active', 't_ChangeStatusActive', '_sys_et_txt_subject_profile_change_status_active', '_sys_et_txt_body_profile_change_status_active'),
@@ -1020,6 +1021,7 @@ CREATE TABLE `sys_objects_report` (
   `table_main` varchar(32) NOT NULL,
   `table_track` varchar(32) NOT NULL,
   `is_on` tinyint(4) NOT NULL default '1',
+  `base_url` varchar(256) NOT NULL default '',
   `trigger_table` varchar(32) NOT NULL,
   `trigger_field_id` varchar(32) NOT NULL,
   `trigger_field_author` varchar(32) NOT NULL,

+ 8 - 2
modules/boonex/english/data/langs/system/en.xml

@@ -63,7 +63,6 @@
 	<string name="_Please enter n1-n2 characters"><![CDATA[Please enter {0}-{1} characters]]></string>
 	<string name="_Please select value"><![CDATA[Please select a value from the list]]></string>
 	<string name="_Preview"><![CDATA[Preview]]></string>
-
 	<string name="_report_counter"><![CDATA[{0}]]></string>
 	<string name="_report_do_report"><![CDATA[Report]]></string>
 	<string name="_report_do_report_by"><![CDATA[Reported by]]></string>
@@ -72,7 +71,6 @@
 	<string name="_report_err_not_enabled"><![CDATA[The feature is not available right now. Please, try again later.]]></string>
 	<string name="_report_err_wrong_type"><![CDATA[Wrong report type.]]></string>
 	<string name="_report_reported_as"><![CDATA[Reported as:]]></string>
-
 	<string name="_RSS_Feed_Title_Common"><![CDATA[{0} RSS]]></string>
 	<string name="_RSS_Feed_Title_Profile"><![CDATA[{0}'s Recent {1}]]></string>
 	<string name="_Rate"><![CDATA[Rate]]></string>
@@ -1472,6 +1470,12 @@ If it is not enabled then please consider implement this optimization, since it
 <p>Your comment was replied. It reads:</p>
 <p>{reply_text}</p>
 <p>Please refer to comment page for more details: <a href="{comment_url}">My Comment</a></p>
+<bx_include_auto:_email_footer.html />]]></string>
+	<string name="_sys_et_txt_body_system_reported"><![CDATA[<bx_include_auto:_email_header.html />
+<p>Hello,</p>
+<p>New report with <b>{report_type}</b> type was received. It reads:</p>
+<p>{report_text}</p>
+<p>Please refer to content page for more details <a href="{report_url}">here</a>.</p>
 <bx_include_auto:_email_footer.html />]]></string>
 	<string name="_sys_et_txt_body_confirmation"><![CDATA[<bx_include_auto:_email_header.html />
 <p>Hello!</p>
@@ -1548,6 +1552,7 @@ If it is not enabled then please consider implement this optimization, since it
 	<string name="_sys_et_txt_body_modules_upgrade_failed"><![CDATA[<b>{0}</b> module: {1}<br />]]></string>
 	<string name="_sys_et_txt_name_system_admin_email"><![CDATA[Message sending from the Admin Panel]]></string>
 	<string name="_sys_et_txt_name_system_comment_replied"><![CDATA[The letter is sent to members whose comment was replied]]></string>
+	<string name="_sys_et_txt_name_system_reported"><![CDATA[New report notification]]></string>
 	<string name="_sys_et_txt_name_system_confirmation"><![CDATA[Profile e-mail confirmation message]]></string>
 	<string name="_sys_et_txt_name_system_delayed_module_uninstall"><![CDATA[Delayed module uninstall notification]]></string>
 	<string name="_sys_et_txt_name_system_forgot"><![CDATA[Reset password message]]></string>
@@ -1565,6 +1570,7 @@ If it is not enabled then please consider implement this optimization, since it
 	<string name="_sys_et_txt_name_bg_operation_failed"><![CDATA[Background operation failed]]></string>
 	<string name="_sys_et_txt_subject_admin_email"><![CDATA[Message from <SiteName> Admin: <MessageSubject>]]></string>
 	<string name="_sys_et_txt_subject_comment_replied"><![CDATA[Your comment was replied]]></string>
+	<string name="_sys_et_txt_subject_system_reported"><![CDATA[New report notification]]></string>
 	<string name="_sys_et_txt_subject_confirmation"><![CDATA[Confirm Your Email (ACTION REQUIRED)]]></string>
 	<string name="_sys_et_txt_subject_delayed_module_uninstall"><![CDATA[Delayed {Module} module uninstall: {Result}]]></string>
 	<string name="_sys_et_txt_subject_forgot"><![CDATA[Reset Your Password]]></string>

+ 8 - 2
modules/boonex/russian/data/langs/system/ru.xml

@@ -63,7 +63,6 @@
 	<string name="_Please enter n1-n2 characters"><![CDATA[Пожалуйста, введите {0}-{1} символов]]></string>
 	<string name="_Please select value"><![CDATA[Пожалуйста, выберите значение из списка]]></string>
 	<string name="_Preview"><![CDATA[Предпросмотр]]></string>
-
 	<string name="_report_counter"><![CDATA[{0}]]></string>
 	<string name="_report_do_report"><![CDATA[Пожаловаться]]></string>
 	<string name="_report_do_report_by"><![CDATA[Пожаловались]]></string>
@@ -72,7 +71,6 @@
 	<string name="_report_err_not_enabled"><![CDATA[Жалоба не может быть принята в данный момент. Пожалуйста, попробуйте позднее.]]></string>
 	<string name="_report_err_wrong_type"><![CDATA[Неправильный тип жалобы.]]></string>
 	<string name="_report_reported_as"><![CDATA[Тип жалобы:]]></string>
-
 	<string name="_RSS_Feed_Title_Common"><![CDATA[{0} RSS]]></string>
 	<string name="_RSS_Feed_Title_Profile"><![CDATA[{0} недавние {1}]]></string>
 	<string name="_Rate"><![CDATA[Оценить]]></string>
@@ -1472,6 +1470,12 @@
 <p>На Ваш комментарий ответили. Ответ:</p>
 <p>{reply_text}</p>
 <p>Пожалуйста, перейдите на страницу комментария для дополнительной информации: <a href="{comment_url}">Мой Комментарий</a></p>
+<bx_include_auto:_email_footer.html />]]></string>
+	<string name="_sys_et_txt_body_system_reported"><![CDATA[<bx_include_auto:_email_header.html />
+<p>Привет,</p>
+<p>Была получена новая жалоба с типом <b>{report_type}</b>. Сообщение:</p>
+<p>{report_text}</p>
+<p>Для получения дополнительной информации, пожалуйста, перейдите на <a href="{report_url}">страницу контента</a>.</p>
 <bx_include_auto:_email_footer.html />]]></string>
 	<string name="_sys_et_txt_body_confirmation"><![CDATA[<bx_include_auto:_email_header.html />
 <p>Привет!</p>
@@ -1548,6 +1552,7 @@
 	<string name="_sys_et_txt_body_modules_upgrade_failed"><![CDATA[<b>{0}</b> молуль: {1}<br />]]></string>
 	<string name="_sys_et_txt_name_system_admin_email"><![CDATA[Посылка сообщения из Панели Администратора]]></string>
 	<string name="_sys_et_txt_name_system_comment_replied"><![CDATA[Сообщение для посылки пользователям, чьи комментарии были отвечены]]></string>
+	<string name="_sys_et_txt_name_system_reported"><![CDATA[Уведомление о новой жалобе]]></string>
 	<string name="_sys_et_txt_name_system_confirmation"><![CDATA[Сообщение для подтверждения эл. адреса профиля]]></string>
 	<string name="_sys_et_txt_name_system_delayed_module_uninstall"><![CDATA[Уведомление об отложенном демонтировании модуля]]></string>
 	<string name="_sys_et_txt_name_system_forgot"><![CDATA[Сообщение о сбросе пароля]]></string>
@@ -1565,6 +1570,7 @@
 	<string name="_sys_et_txt_name_bg_operation_failed"><![CDATA[Фоновая операция не удалась]]></string>
 	<string name="_sys_et_txt_subject_admin_email"><![CDATA[Сообщение от <SiteName> Админа: <MessageSubject>]]></string>
 	<string name="_sys_et_txt_subject_comment_replied"><![CDATA[Ваш комментарий был отвечен]]></string>
+	<string name="_sys_et_txt_subject_system_reported"><![CDATA[Уведомление о новой жалобе]]></string>
 	<string name="_sys_et_txt_subject_confirmation"><![CDATA[Подтвердите свой эл. адрес (ОБЯЗАТЕЛЬНО)]]></string>
 	<string name="_sys_et_txt_subject_delayed_module_uninstall"><![CDATA[Отложенный демонтаж модуля {Module}: {Result}]]></string>
 	<string name="_sys_et_txt_subject_forgot"><![CDATA[Сбросьте свой пароль]]></string>

+ 1 - 1
template/css/report.css

@@ -17,7 +17,7 @@ div.bx-report-by-list-cnt {
 	max-width: 20rem;
 	overflow: auto;
 }
-div.bx-report-by-list div.bx-base-pofile-unit {
+div.bx-report-by-list div.bx-def-unit {
 	float: none;
 	margin-right: 0px;
 	margin-bottom: 0px;

+ 3 - 0
template/profile_unit.html

@@ -0,0 +1,3 @@
+<div class="bx-def-unit bx-def-margin-bottom bx-def-margin-sec-right">
+    <img class="bx-def-thumb bx-def-thumb-size" src="__thumb_url__" /><div class="bx-def-unit-info bx-def-thumb-size-max-height bx-def-padding-sec-left"><span class="bx-def-unit-info-title">__title__</span></div>
+</div>

+ 9 - 1
template/scripts/BxBaseReport.php

@@ -150,7 +150,7 @@ class BxBaseReport extends BxDolReport
 		$iAuthorId = $this->_getAuthorId();
         $aReport = $this->_oQuery->getReport($iObjectId);
 
-        if(!$this->isAllowedReport() && (int)$aReport['count'] == 0)
+        if(!$this->isAllowedReport() && (!$this->isAllowedReportView() || (int)$aReport['count'] == 0))
             return '';
 
         $aParams['is_reported'] = $this->_oQuery->isPerformed($iObjectId, $iAuthorId) ? true : false;
@@ -274,6 +274,14 @@ class BxBaseReport extends BxDolReport
 			if($iId != 0 && $this->_oQuery->putReport($iObjectId)) {
 				$this->_trigger();
 
+        		$aTemplate = BxDolEmailTemplates::getInstance()->parseTemplate('t_Reported', array(
+        			'report_type' => $sType,
+        			'report_text' => $sText,
+        			'report_url' => $this->getBaseUrl(),
+        		));
+        		if($aTemplate)
+        			sendMail(getParam('site_email'), $aTemplate['Subject'], $aTemplate['Body']);
+
 		        $oZ = new BxDolAlerts($this->_sSystem, 'doReport', $iObjectId, $iAuthorId, array('report_id' => $iId, 'report_author_id' => $iAuthorId, 'object_author_id' => $iObjectAuthorId, 'type' => $sType, 'text' => $sText));
 		        $oZ->alert();