AntonLV 13 лет назад
Родитель
Сommit
da35e71734

+ 3 - 5
inc/classes/BxDolCronCmd.php

@@ -113,14 +113,12 @@ class BxDolCronCmd extends BxDolCron {
         $iDeletedViews = $oBxViews->maintenance ();
         $iDeletedViews = $oBxViews->maintenance ();
 
 
         // clean old votes
         // clean old votes
-        bx_import('BxDolVoting');
-        $oBxVotes = new BxDolVoting('', 0);
-        $iDeletedVotes = $oBxVotes->maintenance ();
+        bx_import('BxDolVote');
+        BxDolVote::maintenance();
 
 
         // clean comments ratings
         // clean comments ratings
         bx_import('BxDolCmts');
         bx_import('BxDolCmts');
-        $oBxCmts = new BxDolCmts('', 0);
-        $iDeletedCommentVotes = $oBxCmts->maintenance ();
+        BxDolCmts::maintenance();
 
 
         // clean storage engine expired private file tokens
         // clean storage engine expired private file tokens
         bx_import('BxDolStorage');
         bx_import('BxDolStorage');

+ 2 - 2
inc/classes/BxDolSearch.php

@@ -714,8 +714,8 @@ class BxDolSearchResult {
      */
      */
     function getRatePart () {
     function getRatePart () {
         if ($this->iRate == 1) {
         if ($this->iRate == 1) {
-            bx_import('BxTemplVotingView');
-           $this->oRate = new BxTemplVotingView($this->aCurrent['name'], 0, 0);
+            bx_import('BxTemplVoteView');
+           $this->oRate = new BxTemplVoteView($this->aCurrent['name'], 0, 0);
         }
         }
     }
     }
 
 

+ 473 - 0
inc/classes/BxDolVote.php

@@ -0,0 +1,473 @@
+<?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    DolphinCore Dolphin Core
+ * @{
+ */
+
+bx_import('BxDolVoteQuery');
+
+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');
+
+define('BX_DOL_VOTE_USAGE_BLOCK', 'block');
+define('BX_DOL_VOTE_USAGE_INLINE', 'inline');
+define('BX_DOL_VOTE_USAGE_DEFAULT', BX_DOL_VOTE_USAGE_BLOCK);
+
+/** 
+ * @page objects 
+ * @section vote Vote
+ * @ref BxDolVote
+ */
+
+/**
+ * Vote for any content
+ *
+ * Related classes:
+ * - BxDolVoteQuery - vote database queries
+ * - BxBaseVoteView - vote base representation
+ * - BxTemplVoteView - custom template representation
+ *
+ * AJAX vote for any content. Big and small vote stars are supported.
+ *
+ * To add vote section to your site 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
+ * - MaxValue - max vote value, 5 by default
+ * - IsUndo - is Undo enabled 
+ * - 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
+ *
+ * You can refer to BoonEx modules for sample record in this table.
+ *
+ *
+ *
+ * @section example Example of usage:
+ * After filling in the table you can show big vote in any place, using the following code:
+ * @code
+ * bx_import('BxTemplVoteView');
+ * $o = new BxTemplVoteView ('value of ObjectName field', $iYourEntryId);
+ * if (!$o->isEnabled()) return '';
+ *     echo $o->getBigVote (1); // 1 - rate is allowed
+ * @endcode
+ *
+ * And small vote, using the following code:
+ * @code
+ * $o = new BxTemplVoteView ('value of ObjectName field', $iYourEntryId);
+ * if (!$o->isEnabled()) return '';
+ *     echo $o->getSmallVote (0); // 0 - rate is not allowed, like readonly votes
+ * @endcode
+ *
+ * In some cases votes are already in database and there is no need to execute additional query to get ratings,
+ * so you can use the following code:
+ * @code
+ * $o = new BxTemplVoteView ('value of ObjectName field', 0);
+ * foreach ($aRecords as $aData)
+ *     echo $o->getJustVoteElement(0, $aData['ID'], $aData['voting_rate']);
+ * @endcode
+ *
+ * Please note that you never need to use BxDolVote class directly, use BxTemplVoteView instead.
+ * Also if you override vote class with your own then make it child of BxTemplVoteView class.
+ *
+ *
+ *
+ * @section acl Memberships/ACL:
+ * vote - ACTION_ID_VOTE
+ *
+ *
+ *
+ * @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
+ *
+ */
+
+/*
+
+CREATE TABLE IF NOT EXISTS `sample_votes` (
+  `object_id` int(11) NOT NULL default '0',
+  `count` int(11) NOT NULL default '0',
+  `sum` int(11) NOT NULL default '0',
+  UNIQUE KEY `object_id` (`object_id`)
+) ENGINE=MYISAM DEFAULT CHARSET=utf8;
+
+CREATE TABLE IF NOT EXISTS `sample_votes_track` (
+  `object_id` int(11) NOT NULL default '0',
+  `author_id` int(11) NOT NULL default '0',
+  `author_nip` int(11) NOT NULL default '0',
+  `value` tinyint(4) NOT NULL default '0',
+  `date` int(11) NOT NULL default '0',
+  KEY `vote` (`object_id`, `author_nip`)
+) ENGINE=MYISAM DEFAULT CHARSET=utf8;
+
+ */
+
+
+class BxDolVote extends BxDol
+{
+    var $_iId = 0;    ///< item id to be rated
+    var $_sSystem = ''; ///< current rating system name
+    var $_aSystem = array(); ///< current rating system array
+
+    var $_oQuery = null;
+
+    protected function __construct($sSystem, $iId, $iInit = 1)
+    {
+        parent::__construct();
+
+        $this->_aSystems = $this->getSystems();
+        if(!isset($this->_aSystems[$sSystem]))
+			return;
+
+        $this->_sSystem = $sSystem;
+		$this->_aSystem = $this->_aSystems[$sSystem];
+
+		if(!$this->isEnabled()) 
+			return;
+
+        $this->_oQuery = new BxDolVoteQuery($this);
+
+        if($iInit)
+			$this->init($iId);
+    }
+
+	/**
+     * get votes object instanse
+     * @param $sSys vote object name 
+     * @param $iId associated content id, where vote is available
+     * @param $iInit perform initialization
+     * @return null on error, or ready to use class instance
+     */
+    public static function getObjectInstance($sSys, $iId, $iInit = true) 
+    {
+    	if(isset($GLOBALS['bxDolClasses']['BxDolVote!' . $sSys . $iId]))
+            return $GLOBALS['bxDolClasses']['BxDolVote!' . $sSys . $iId];
+
+        $aSystems = self::getSystems();
+        if(!isset($aSystems[$sSys]))
+            return null;
+
+        bx_import('BxTemplVoteView');
+        $sClassName = 'BxTemplVoteView';
+        if(!empty($aSystems[$sSys]['class_name'])) {
+        	$sClassName = $aSystems[$sSys]['class_name'];
+        	if(!empty($aSystems[$sSys]['class_file']))
+                require_once(BX_DIRECTORY_PATH_ROOT . $aSystems[$sSys]['class_file']);
+            else
+                bx_import($sClassName);
+        }
+
+        $o = new $sClassName($sSys, $iId, true);
+        return ($GLOBALS['bxDolClasses']['BxDolVote!' . $sSys . $iId] = $o);
+    }
+
+    public static function &getSystems()
+    {
+        if(!isset($GLOBALS['bx_dol_vote_systems']))
+			$GLOBALS['bx_dol_vote_systems'] = BxDolDb::getInstance()->fromCache('sys_objects_vote', 'getAllWithKey', '
+        		SELECT
+                    `ID` as `id`,
+                    `Name` AS `name`,
+                    `TableMain` AS `table_main`,
+                    `TableTrack` AS `table_track`,
+                    `PostTimeout` AS `post_timeout`,
+                    `MinValue` AS `min_value`,
+                    `MaxValue` AS `max_value`,
+                    `IsUndo` AS `is_undo`,
+                    `IsOn` AS `is_on`,
+                    `TriggerTable` AS `trigger_table`,
+                    `TriggerFieldId` AS `trigger_field_id`,
+                    `TriggerFieldRate` AS `trigger_field_rate`,
+                    `TriggerFieldRateCount` AS `trigger_field_count`,
+                    `ClassName` AS `class_name`,
+                    `ClassFile` AS `class_file`
+                FROM `sys_objects_vote`', 'name');
+
+        return $GLOBALS['bx_dol_vote_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_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()) 
+        	return;
+
+        if(empty($this->_iId) && $iId)
+			$this->setId($iId);
+    }
+
+    /**
+     * Settings functions
+     */
+	public function getSystemId()
+    {
+        return $this->_aSystem['id'];
+    }
+
+    public function getSystemName()
+    {
+        return $this->_sSystem;
+    }
+
+	public function getSystemInfo()
+    {
+        return $this->_aSystem;
+    }
+
+	public function getId()
+    {
+        return $this->_iId;
+    }
+
+    public function isEnabled()
+    {
+        return (int)$this->_aSystem['is_on'] == 1;
+    }
+
+	public function isUndo()
+    {
+        return (int)$this->_aSystem['is_undo'] == 1;
+    }
+
+	public function isLikeMode()
+    {
+    	$bUndo = $this->isUndo();
+    	$iMinValue = $this->getMinValue();
+    	$iMaxValue = $this->getMaxValue();
+
+    	return $iMinValue == $iMaxValue && $bUndo;
+    }
+
+	public function getMinValue()
+    {
+        return (int)$this->_aSystem['min_value'];
+    }
+
+	public function getMaxValue()
+    {
+        return (int)$this->_aSystem['max_value'];
+    }
+
+    public function setId($iId)
+    {
+        if($iId == $this->getId())
+        	return;
+
+        $this->_iId = $iId;
+    }
+
+
+	/**
+     * Interface functions for outer usage
+     */
+	public function getStatCounter()
+    {
+    	$aVote = $this->_oQuery->getVote($this->getId());
+    	return $aVote['count'];
+    }
+
+	public function getStatRate()
+    {
+    	$aVote = $this->_oQuery->getVote($this->getId());
+    	return $aVote['rate'];
+    }
+
+	public function getSqlParts($sMainTable, $sMainField)
+    {
+        if(!$this->isEnabled())
+        	return array();
+
+		return $this->_oQuery->getSqlParts($sMainTable, $sMainField);
+    }
+
+
+	/**
+     * Actions functions
+     */
+    public function actionVote()
+    {
+    	if(!$this->isEnabled()) {
+			$this->_echoResultJson(array('code' => 1));
+        	return;
+		}
+
+		$iObjectId = $this->getId();
+		$iAuthorId = $this->_getAuthorId();
+		$iAuthorIp = $this->_getAuthorIp();
+
+		$bUndo = $this->isUndo() && $this->_oQuery->isVoted($iObjectId, $iAuthorId, $iAuthorIp) ? true : false;
+
+		if(!$bUndo && !$this->isAllowedVote()) {
+			$this->_echoResultJson(array('code' => 2, 'msg' => $this->msgErrAllowedVote()));
+        	return;
+		}
+
+    	if(!$bUndo && !$this->_oQuery->isPostTimeoutEnded($iObjectId, $iAuthorIp)) {
+			$this->_echoResultJson(array('code' => 3, 'msg' => _t('_vote_err_duplicate_vote')));
+        	return;
+		}
+
+    	$iValue = bx_get('value');
+		if($iValue === false) {
+			$this->_echoResultJson(array('code' => 4));
+        	return;
+		}
+
+    	$iValue = bx_process_input($iValue, BX_DATA_INT);
+
+		$iMinValue = $this->getMinValue();
+        if($iValue < $iMinValue)
+            $iValue = $iMinValue;
+
+    	$iMaxValue = $this->getMaxValue();
+        if($iValue > $iMaxValue)
+			$iValue = $iMaxValue;
+
+	    if(!$this->_oQuery->putVote($iObjectId, $iAuthorId, $iAuthorIp, $iValue, $bUndo)) {
+	    	$this->_echoResultJson(array('code' => 5));
+        	return;
+	    }
+
+		$this->_triggerVote();
+
+		$oZ = new BxDolAlerts($this->_sSystem, 'rate', $this->getId(), $iAuthorId, array('value' => $iValue, 'undo' => $bUndo));
+        $oZ->alert();
+
+        $aVote = $this->_oQuery->getVote($iObjectId);
+        $this->_echoResultJson(array(
+        	'code' => 0, 
+        	'rate' => $aVote['rate'],
+        	'count' => $aVote['count'],
+        	'countf' => (int)$aVote['count'] > 0 ? $this->_getLabelCounter($aVote['count']) : ''
+        ));
+    }
+
+	public function actionGetVotedBy() {
+        if (!$this->isEnabled())
+           return '';
+
+        return $this->_getVotedBy();
+    }
+
+    /** 
+     * Permissions functions
+     */
+	public function checkAction ($iAction, $isPerformAction = false)
+    {
+        $iId = $this->_getAuthorId();
+        $check_res = checkAction($iId, $iAction, $isPerformAction);
+        return $check_res[CHECK_ACTION_RESULT] === CHECK_ACTION_RESULT_ALLOWED;
+    }
+
+    public function checkActionErrorMsg ($iAction)
+    {
+        $iId = $this->_getAuthorId();
+        $check_res = checkAction($iId, $iAction);
+        return $check_res[CHECK_ACTION_RESULT] !== CHECK_ACTION_RESULT_ALLOWED ? $check_res[CHECK_ACTION_MESSAGE] : '';
+    }
+
+	public function isAllowedVote($isPerformAction = false)
+    {
+    	if(isAdmin())
+    		return true;
+
+        return $this->checkAction(ACTION_ID_VOTE, $isPerformAction); 
+    }
+
+    public function msgErrAllowedVote()
+    { 
+        return $this->checkActionErrorMsg(ACTION_ID_VOTE);
+    }
+
+
+    /** 
+     * Internal functions
+     */
+	protected function _getAuthorId ()
+    {
+        return isMember() ? bx_get_logged_profile_id() : 0;
+    }
+
+    protected function _getAuthorIp ()
+    {
+        return $_SERVER['REMOTE_ADDR'];
+    }
+
+	protected function _getAuthorInfo($iAuthorId = 0)
+    {
+    	$oProfile = $this->_getAuthorObject($iAuthorId);
+
+		return array(
+			$oProfile->getDisplayName(), 
+			$oProfile->getUrl(), 
+			$oProfile->getThumb(),
+			$oProfile->getUnit()
+		);
+    }
+
+	protected function _getAuthorObject($iAuthorId = 0)
+    {
+    	bx_import('BxDolProfile');
+		$oProfile = BxDolProfile::getInstance($iAuthorId);
+		if (!$oProfile) {
+			bx_import('BxDolProfileUndefined');
+			$oProfile = BxDolProfileUndefined::getInstance();
+		}
+
+		return $oProfile;
+    }
+
+	protected function _triggerVote()
+    {
+        if(!$this->_aSystem['trigger_table'])
+			return false;
+
+        $iId = $this->getId();
+        if(!$iId)
+            return false;
+
+        return $this->_oQuery->updateTriggerTable($iId);
+    }
+}
+
+/** @} */ 

+ 126 - 0
inc/classes/BxDolVoteQuery.php

@@ -0,0 +1,126 @@
+<?php
+/**
+ * @package     Dolphin Core
+ * @copyright   Copyright (c) BoonEx Pty Limited - http://www.boonex.com/
+ * @license     CC-BY - http://creativecommons.org/licenses/by/3.0/
+ */
+defined('BX_DOL') or die('hack attempt');
+
+bx_import('BxDolDb');
+
+/**
+ * @see BxDolVote
+ */
+class BxDolVoteQuery extends BxDolDb
+{
+	protected $_oModule;
+
+    protected $_sTable;
+    protected $_sTableTrack;
+    protected $_sTriggerTable;
+    protected $_sTriggerFieldId;
+    protected $_sTriggerFieldRate;
+    protected $_sTriggerFieldCount;
+
+    protected $_iPostTimeout;
+
+
+    public function __construct(&$oModule)
+    {
+        parent::BxDolDb();
+
+        $this->_oModule = $oModule;
+
+    	$aSystem = $this->_oModule->getSystemInfo();
+        $this->_sTable = $aSystem['table_main'];
+        $this->_sTableTrack = $aSystem['table_track'];
+        $this->_sTriggerTable = $aSystem['trigger_table'];
+        $this->_sTriggerFieldId = $aSystem['trigger_field_id'];
+        $this->_sTriggerFieldRate = $aSystem['trigger_field_rate'];
+        $this->_sTriggerFieldCount = $aSystem['trigger_field_count'];
+
+        $this->_iPostTimeout = (int)$aSystem['post_timeout'];
+    }
+
+	public function isPostTimeoutEnded($iObjectId, $sAuthorIp)
+    {
+    	if($this->_iPostTimeout == 0) 
+    		return true;
+
+		$sQuery = $this->prepare("SELECT `object_id` FROM `{$this->_sTableTrack}` WHERE `object_id` = ? AND `author_nip` = ? AND `date` > (UNIX_TIMESTAMP() - ?)", $iObjectId, ip2long($sAuthorIp), $this->_iPostTimeout);
+		return (int)$this->getOne($sQuery) == 0;
+    }
+
+	public function getVote($iObjectId)
+    {
+        $sQuery = $this->prepare("SELECT `count` as `count`, `sum` as `sum`, ROUND(`sum` / `count`, 2) AS `rate` FROM {$this->_sTable} WHERE `object_id` = ? LIMIT 1", $iObjectId);
+
+        $aResult = $this->getRow($sQuery);
+		if(empty($aResult) || !is_array($aResult))
+			$aResult = array('count' => 0, 'sum' => 0, 'rate' => 0);
+
+		return $aResult;
+    }
+
+    public function isVoted($iObjectId, $iAuthorId, $sAuthorIp)
+    {
+    	$iAuthorNip = ip2long($sAuthorIp);
+
+		$sQuery = $this->prepare("SELECT `object_id` FROM `{$this->_sTableTrack}` WHERE `object_id` = ? AND `author_nip` = ? LIMIT 1", $iObjectId, $iAuthorNip);
+		return (int)$this->getOne($sQuery) != 0;
+    }
+
+	public function putVote($iObjectId, $iAuthorId, $sAuthorIp, $iValue, $bUndo = false)
+    {
+    	$sQuery = $this->prepare("SELECT `object_id` FROM `{$this->_sTable}` WHERE `object_id` = ? LIMIT 1", $iObjectId);
+        $bExists = (int)$this->getOne($sQuery) != 0;
+        if(!$bExists && $bUndo)
+        	return false;
+
+        if(!$bExists)
+			$sQuery = $this->prepare("INSERT INTO {$this->_sTable} SET `object_id` = ?, `count` = '1', `sum` = ?", $iObjectId, $iValue);
+        else 
+        	$sQuery = $this->prepare("UPDATE `{$this->_sTable}` SET `count` = `count` " . ($bUndo ? "-" : "+") . " 1, `sum` = `sum` " . ($bUndo ? "-" : "+") . " ? WHERE `object_id` = ?", $iValue, $iObjectId);
+
+        if((int)$this->query($sQuery) == 0) 
+        	return false;
+
+		$iAuthorNip = ip2long($sAuthorIp);
+        if($bUndo)
+        	$sQuery = $this->prepare("DELETE FROM `{$this->_sTableTrack}` WHERE `object_id` = ? AND `author_nip` = ? LIMIT 1", $iObjectId, $iAuthorNip);
+        else
+        	$sQuery = $this->prepare("INSERT INTO `{$this->_sTableTrack}` SET `object_id` = ?, `author_id` = ?, `author_nip` = ?, `value` = ?, `date` = UNIX_TIMESTAMP()", $iObjectId, $iAuthorId, $iAuthorNip, $iValue);
+
+        return (int)$this->query($sQuery) > 0;
+    }
+
+	public function updateTriggerTable($iObjectId) {
+		$aVote = $this->getVote($iObjectId);
+		if(empty($aVote) || !is_array($aVote))
+			return false;
+
+        $sQuery = $this->prepare("UPDATE `{$this->_sTriggerTable}` SET `{$this->_sTriggerFieldCount}` = ?, `{$this->_sTriggerFieldRate}` = ? WHERE `{$this->_sTriggerFieldId}` = ?", $aVote['count'], $aVote['rate'], $iObjectId);
+        return (int)$this->query($sQuery) > 0;
+    }
+
+    function getSqlParts($sMainTable, $sMainField)
+    {
+    	if(empty($sMainTable) || empty($sMainField))
+			return array();
+
+        $sPre = $this->_aSystem['row_prefix'];
+        $sTable = $this->_aSystem['table_rating'];
+
+        return array (
+            'fields' => ",`{$this->_sTable}`.`count` as `vote_count`, (`{$this->_sTable}`.`sum` / `{$this->_sTable}`.`count`) AS `vote_rate` ",
+            'join' => $this->prepare(" LEFT JOIN `{$this->_sTable}` ON (`{$this->_sTable}`.`object_id` = ?) ", "`{$sMainTable}`.`{$sMainField}`"),
+        );
+    }
+
+    function getVotedBy($iObjectId)
+    {
+    	$sQuery = $this->prepare("SELECT `author_id` FROM `{$this->_sTableTrack}` WHERE `object_id`=?", $iObjectId);
+    	return $this->getColumn($sQuery);
+    }
+}
+

+ 0 - 379
inc/classes/BxDolVoting.php

@@ -1,379 +0,0 @@
-<?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    DolphinCore Dolphin Core
- * @{
- */
-
-bx_import('BxDolVotingQuery');
-
-define( 'BX_PERIOD_PER_VOTE', 7 * 86400 ); ///< user can vote again for the same content after this number of seconds
-define( 'BX_OLD_VOTES', 365*86400 ); ///< votes older than this number of seconds will be deleted automatically
-
-/** 
- * @page objects 
- * @section votings Votings
- * @ref BxDolVoting
- */
-
-/**
- * Votings for any content
- *
- * Related classes:
- * - BxDolVotingQuery - votings database queries
- * - BxBaseVotingView - votings base representation
- * - BxTemplVotingView - custom template representation
- *
- * AJAX votings for any content. Big and small votings stars are supported.
- *
- * To add votings section to your site you need to add a record to 'sys_objects_vote' table:
- *
- * - ID - autoincremented id for internal usage
- * - ObjectName - your unique module name, with vendor prefix, lowercase and spaces are underscored
- * - TableRating - table name where sumarry votigs are stored
- * - TableTrack - table name where each vote is stored
- * - RowPrefix - row prefix for TableRating
- * - MaxVotes - max vote number, 5 by default
- * - PostName - post variable name with rating
- * - IsDuplicate - number of seconds to not allow duplicate vote (for some bad reason it is define here)
- * - IsOn - is this vote object enabled
- * - ClassName - custom class name for HotOrNot @ref BxDolRate
- * - ClassFile - custom class path for HotOrNot
- * - TriggerTable - table to be updated upon each vote
- * - TriggerFieldRate - TriggerTable table field with average rate
- * - TriggerFieldRateCount - TriggerTable table field with votes count
- * - TriggerFieldId - TriggerTable table field with unique record id, primary key
- * - OverrideClassName - your custom class name, if you overrride default class
- * - OverrideClassFile - your custom class path
- *
- * You can refer to BoonEx modules for sample record in this table.
- *
- *
- *
- * @section example Example of usage:
- * After filling in the table you can show big votings in any place, using the following code:
- * @code
- * bx_import('BxTemplVotingView');
- * $o = new BxTemplVotingView ('value of ObjectName field', $iYourEntryId);
- * if (!$o->isEnabled()) return '';
- *     echo $o->getBigVoting (1); // 1 - rate is allowed
- * @endcode
- *
- * And small votings, using the following code:
- * @code
- * $o = new BxTemplVotingView ('value of ObjectName field', $iYourEntryId);
- * if (!$o->isEnabled()) return '';
- *     echo $o->getSmallVoting (0); // 0 - rate is not allowed, like readonly votings
- * @endcode
- *
- * In some cases votes are already in database and there is no need to execute additional query to get ratings,
- * so you can use the following code:
- * @code
- * $o = new BxTemplVotingView ('value of ObjectName field', 0);
- * foreach ($aRecords as $aData)
- *     echo $o->getJustVotingElement(0, $aData['ID'], $aData['voting_rate']);
- * @endcode
- *
- * Please note that you never need to use BxDolVoting class directly, use BxTemplVotingView instead.
- * Also if you override votings class with your own then make it child of BxTemplVotingView class.
- *
- *
- *
- * @section acl Memberships/ACL:
- * vote - ACTION_ID_VOTE
- *
- *
- *
- * @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
- *
- */
-class BxDolVoting extends BxDol
-{
-    var $_iId = 0;    ///< item id to be rated
-    var $_iCount = 0; ///< number of votes
-    var $_fRate = 0; ///< average rate
-    var $_sSystem = 'profile'; ///< current rating system name
-
-    var $_aSystem = array (); ///< current rating system array
-
-    var $_oQuery = null;
-
-    /**
-     * Constructor
-     */
-    function BxDolVoting( $sSystem, $iId, $iInit = 1)
-    {
-        parent::BxDol();
-
-        $this->_aSystems =& $this->getSystems();
-
-        $this->_sSystem = $sSystem;
-        if (isset($this->_aSystems[$sSystem]))
-            $this->_aSystem = $this->_aSystems[$sSystem];
-        else
-            return;
-
-        $this->_oQuery = new BxDolVotingQuery($this->_aSystem);
-
-        if ($iInit)
-            $this->init($iId);
-
-        if (!$this->isEnabled()) return;
-
-        $iVoteResult = $this->_getVoteResult ();
-        if ($iVoteResult)
-        {
-            if (!$this->makeVote ($iVoteResult))
-            {
-                exit;
-            }
-            $this->initVotes ();
-            echo $this->getVoteRate() . ',' . $this->getVoteCount();
-            exit;
-        }
-    }
-
-    function & getSystems ()
-    {
-        if (isset($GLOBALS['bx_dol_voting_systems'])) {
-            return $GLOBALS['bx_dol_voting_systems'];
-        }
-
-        $oDb = BxDolDb::getInstance();
-        $oCache = $oDb->getDbCacheObject();
-
-        $GLOBALS['bx_dol_voting_systems'] = $oCache->getData($oDb->genDbCacheKey('sys_objects_vote'));
-
-        if (null === $GLOBALS['bx_dol_voting_systems']) {
-
-            // cache is empty | load data from DB
-
-            $sQuery  = "SELECT * FROM `sys_objects_vote`";
-            $sRows = $oDb->getAll($sQuery);
-
-            $GLOBALS['bx_dol_voting_systems'] = array();
-            foreach ($sRows as $aRow)
-            {
-                $GLOBALS['bx_dol_voting_systems'][$aRow['ObjectName']] = array
-                (
-                    'table_rating'    => $aRow['TableRating'],
-                    'table_track'    => $aRow['TableTrack'],
-                    'row_prefix'    => $aRow['RowPrefix'],
-                    'max_votes'        => $aRow['MaxVotes'],
-                    'post_name'        => $aRow['PostName'],
-                    'is_duplicate'    => is_int($aRow['IsDuplicate']) ? $aRow['IsDuplicate'] : constant($aRow['IsDuplicate']),
-                    'is_on'            => $aRow['IsOn'],
-
-                    'className'     => $aRow['className'],
-                    'classFile'     => $aRow['classFile'],
-
-                    'trigger_table'            => $aRow['TriggerTable'], // table with field to update on every rating change
-                    'trigger_field_rate'       => $aRow['TriggerFieldRate'], // table field name with rating
-                    'trigger_field_rate_count' => $aRow['TriggerFieldRateCount'], // table field name with rating count
-                    'trigger_field_id'         => $aRow['TriggerFieldId'], // table field name with object id
-
-                    'override_class_name' => $aRow['OverrideClassName'], // new class to override
-                    'override_class_file' => $aRow['OverrideClassFile'], // class file path
-                );
-            }
-
-            // write data into cache file
-
-            $oCache = $oDb->getDbCacheObject();
-            $oCache->setData ($oDb->genDbCacheKey('sys_objects_vote'), $GLOBALS['bx_dol_voting_systems']);
-        }
-
-        return $GLOBALS['bx_dol_voting_systems'];
-    }
-
-    function init ($iId)
-    {
-        if (!$iId)
-            $iId = $this->_iId;
-
-        if (!$this->isEnabled()) return;
-
-        if (!$this->_iId && $iId)
-        {
-            $this->setId($iId);
-        }
-
-    }
-
-    function initVotes ()
-    {
-        if (!$this->isEnabled()) return;
-        if (!$this->_oQuery) return;
-
-        $a = $this->_oQuery->getVote ($this->getId());
-        if (!$a) return;
-        $this->_iCount = $a['count'];
-        $this->_fRate = $a['rate'];
-    }
-
-    function makeVote ($iVote)
-    {
-        if (!$this->isEnabled()) return false;
-        if ($this->isDublicateVote()) return false;
-        if (!$this->checkAction()) return false;
-
-        if ($this->_sSystem == 'profile' && $this->getId() == getLoggedId())
-            return false;
-
-        if ($this->_oQuery->putVote ($this->getId(), getVisitorIP(), $iVote)) {
-            $this->_triggerVote();
-
-            $oZ = new BxDolAlerts($this->_sSystem, 'rate', $this->getId(), getLoggedId(), array ('rate' => $iVote));
-            $oZ->alert();
-            return true;
-        }
-        return false;
-    }
-
-    function checkAction ()
-    {
-        bx_import('BxDolAcl');
-        if (isset($this->_checkActionResult))
-            return $this->_checkActionResult;
-        $iId = getLoggedId();
-        $check_res = checkAction( $iId, ACTION_ID_VOTE );
-        return ($this->_checkActionResult = ($check_res[CHECK_ACTION_RESULT] == CHECK_ACTION_RESULT_ALLOWED));
-    }
-
-    function isDublicateVote ()
-    {
-        if (!$this->isEnabled()) return false;
-        return $this->_oQuery->isDublicateVote ($this->getId(), getVisitorIP());
-    }
-
-    function getId ()
-    {
-        return $this->_iId;
-    }
-
-    function isEnabled ()
-    {
-        return $this->_aSystem['is_on'];
-    }
-
-    function getMaxVote()
-    {
-        return $this->_aSystem['max_votes'];
-    }
-
-    function getVoteCount()
-    {
-        return $this->_iCount;
-    }
-
-    function getVoteRate()
-    {
-        return $this->_fRate;
-    }
-
-    function getSystemName()
-    {
-        return $this->_sSystem;
-    }
-
-    /**
-     * set id to operate with votes
-     */
-    function setId ($iId)
-    {
-        if ($iId == $this->getId()) return;
-        $this->_iId = $iId;
-        $this->initVotes();
-    }
-
-    function getSqlParts ($sMailTable, $sMailField)
-    {
-        if ($this->isEnabled())
-            return $this->_oQuery->getSqlParts ($sMailTable, $sMailField);
-        else
-            return array();
-    }
-
-
-    function isValidSystem ($sSystem)
-    {
-        return isset($this->_aSystems[$sSystem]);
-    }
-
-    function deleteVotings ($iId)
-    {
-        if (!(int)$iId || !$this->_oQuery) 
-            return false;
-        $this->_oQuery->deleteVotings ($iId);
-        return true;
-    }
-
-    function getTopVotedItem ($iDays, $sJoinTable = '', $sJoinField = '', $sWhere = '')
-    {
-        return $this->_oQuery->getTopVotedItem ($iDays, $sJoinTable, $sJoinField, $sWhere);
-    }
-
-    function getVotedItems ($sIp)
-    {
-        return $this->_oQuery->getVotedItems ($sIp);
-    }
-
-    /**
-     * it is called on cron every day or similar period to clean old votes
-     */
-    function maintenance () {        
-        $iDeletedRecords = 0;
-        $oDb = BxDolDb::getInstance();
-        foreach ($this->_aSystems as $aSystem) {
-            if (!$aSystem['is_on'])
-                continue;
-            $sPre = $aSystem['row_prefix'];
-            $sQuery = $oDb->prepare("DELETE FROM `{$aSystem['table_track']}` WHERE `{$sPre}date` < DATE_SUB(NOW(), INTERVAL ? SECOND)", BX_OLD_VOTES);
-            $iDeletedRecords += $oDb->query($sQuery);
-            $oDb->query("OPTIMIZE TABLE `{$aSystem['table_track']}`");
-        }
-        return $iDeletedRecords;
-    }
-
-    /** private functions
-    *********************************************/
-
-    function _getVoteResult ()
-    {
-        if (empty($_GET[$this->_aSystem['post_name']]) || 0 != strcasecmp($_SERVER['REQUEST_METHOD'], 'POST'))
-            return 0;
-        $iVote = (int)$_GET[$this->_aSystem['post_name']];
-        if (!$iVote)
-            return 0;
-
-        if ($iVote > $this->getMaxVote())
-            $iVote = $this->getMaxVote();
-        if ($iVote < 1)
-            $iVote = 1;
-        return $iVote;
-    }
-
-    function _triggerVote()
-    {
-        if (!$this->_aSystem['trigger_table'])
-            return false;
-        $iId = $this->getId();
-        if (!$iId)
-            return false;
-        $this->initVotes ();
-        $iCount = $this->getVoteCount();
-        $fRate = $this->getVoteRate();
-        return $this->_oQuery->updateTriggerTable($iId, $fRate, $iCount);
-    }
-}
-
-/** @} */ 

+ 0 - 123
inc/classes/BxDolVotingQuery.php

@@ -1,123 +0,0 @@
-<?php
-/**
- * @package     Dolphin Core
- * @copyright   Copyright (c) BoonEx Pty Limited - http://www.boonex.com/
- * @license     CC-BY - http://creativecommons.org/licenses/by/3.0/
- */
-defined('BX_DOL') or die('hack attempt');
-
-bx_import('BxDolDb');
-
-/**
- * @see BxDolVoting
- */
-class BxDolVotingQuery extends BxDolDb
-{
-    var $_aSystem; ///< current voting system
-
-    function BxDolVotingQuery(&$aSystem)
-    {
-        $this->_aSystem = &$aSystem;
-        parent::BxDolDb();
-    }
-
-    function  getVote ($iId)
-    {
-        $sPre = $this->_aSystem['row_prefix'];
-        $sTable = $this->_aSystem['table_rating'];
-
-        $sQuery = $this->prepare("SELECT `{$sPre}rating_count` as `count`, (`{$sPre}rating_sum` / `{$sPre}rating_count`) AS `rate` FROM {$sTable} WHERE `{$sPre}id` = ? LIMIT 1", $iId);
-        return $this->getRow($sQuery);
-    }
-
-    function  putVote ($iId, $sIp, $iRate)
-    {
-        $sPre = $this->_aSystem['row_prefix'];
-
-        $sTable = $this->_aSystem['table_rating'];
-
-        $sQuery = $this->prepare("SELECT `{$sPre}id` FROM $sTable WHERE `{$sPre}id` = ? LIMIT 1", $iId);
-        if ($this->getOne($sQuery))
-        {
-            $sQuery = $this->prepare("UPDATE {$sTable} SET `{$sPre}rating_count` = `{$sPre}rating_count` + 1, `{$sPre}rating_sum` = `{$sPre}rating_sum` + ? WHERE `{$sPre}id` = ?", $iRate, $iId);
-            $ret = $this->query ($sQuery);
-        }
-        else
-        {
-            $sQuery = $this->prepare("INSERT INTO {$sTable} SET `{$sPre}id` = ?, `{$sPre}rating_count` = '1', `{$sPre}rating_sum` = ?", $iId, $iRate);
-            $ret = $this->query ($sQuery);
-        }
-        if (!$ret) return $ret;
-
-        $sTable = $this->_aSystem['table_track'];
-        $sQuery = $this->prepare("INSERT INTO {$sTable} SET `{$sPre}id` = ?, `{$sPre}ip` = ?, `{$sPre}date` = NOW()", $iId, $sIp);
-        return $this->query ($sQuery);
-    }
-
-    function isDublicateVote ($iId, $sIp)
-    {
-        $sPre = $this->_aSystem['row_prefix'];
-        $sTable = $this->_aSystem['table_track'];
-        $iSec = $this->_aSystem['is_duplicate'];
-
-        $sQuery = $this->prepare("SELECT `{$sPre}id` FROM {$sTable} WHERE `{$sPre}ip` = ? AND `{$sPre}id` = ? AND `{$sPre}date` > FROM_UNIXTIME(UNIX_TIMESTAMP() - ?)", $sIp, $iId, $iSec);
-        return $this->getOne ($sQuery);
-
-    }
-
-    function getSqlParts ($sMailTable, $sMailField)
-    {
-        if ($sMailTable)
-            $sMailTable .= '.';
-
-        if ($sMailField)
-            $sMailField = $sMailTable.$sMailField;
-
-        $sPre = $this->_aSystem['row_prefix'];
-        $sTable = $this->_aSystem['table_rating'];
-
-        return array (
-            'fields' => ",$sTable.`{$sPre}rating_count` as `voting_count`, ($sTable.`{$sPre}rating_sum` / $sTable.`{$sPre}rating_count`) AS `voting_rate` ",
-            'join' => $this->prepare(" LEFT JOIN $sTable ON ({$sTable}.`{$sPre}id` = ?) ", $sMailField),
-        );
-    }
-
-    function deleteVotings ($iId)
-    {
-        $sPre = $this->_aSystem['row_prefix'];
-
-        $sTable = $this->_aSystem['table_track'];
-        $sQuery = $this->prepare("DELETE FROM {$sTable} WHERE `{$sPre}id` = ?", $iId);
-        $this->query ($sQuery);
-
-        $sTable = $this->_aSystem['table_rating'];
-        $sQuery = $this->prepare("DELETE FROM {$sTable} WHERE `{$sPre}id` = ?", $iId);
-        return $this->query ($sQuery);
-    }
-
-    function getTopVotedItem ($iDays, $sJoinTable = '', $sJoinField = '', $sWhere = '')
-    {
-        $sPre = $this->_aSystem['row_prefix'];
-        $sTable = $this->_aSystem['table_track'];
-
-        $sJoin = $sJoinTable && $sJoinField ? " INNER JOIN $sJoinTable ON ({$sJoinTable}.{$sJoinField} = $sTable.`{$sPre}id`) " : '';
-
-        $sQuery = $this->prepare("SELECT $sTable.`{$sPre}id`, COUNT($sTable.`{$sPre}id`) AS `voting_count` FROM {$sTable} $sJoin WHERE $sTable.`{$sPre}date` >= DATE_SUB(NOW(), INTERVAL ? DAY) $sWhere GROUP BY $sTable.`{$sPre}id` HAVING `voting_count` > 2 ORDER BY `voting_count` DESC LIMIT 1", $iDays);
-        return $this->getOne ($sQuery);
-    }
-
-    function getVotedItems ($sIp)
-    {
-        $sPre = $this->_aSystem['row_prefix'];
-        $sTable = $this->_aSystem['table_track'];
-        $iSec = $this->_aSystem['is_duplicate'];
-        $sQuery = $this->prepare("SELECT `{$sPre}id` FROM {$sTable} WHERE `{$sPre}ip` = ? AND `{$sPre}date` > FROM_UNIXTIME(UNIX_TIMESTAMP() - ?) ORDER BY `{$sPre}date` DESC", $sIp, $iSec);
-        return $this->getAll ($sQuery);
-    }
-
-    function updateTriggerTable($iId, $fRate, $iCount) {
-        $sQuery = $this->prepare("UPDATE `{$this->_aSystem['trigger_table']}` SET `{$this->_aSystem['trigger_field_rate']}` = ?, `{$this->_aSystem['trigger_field_rate_count']}` = ? WHERE `{$this->_aSystem['trigger_field_id']}` = ?", $fRate, $iCount, $iId);
-        return $this->query($sQuery);
-    }
-}
-

+ 154 - 0
inc/js/classes/BxDolVote.js

@@ -0,0 +1,154 @@
+/**
+ * @package     Dolphin Core
+ * @copyright   Copyright (c) BoonEx Pty Limited - http://www.boonex.com/
+ * @license     CC-BY - http://creativecommons.org/licenses/by/3.0/
+ */
+
+function BxDolVote(options)
+{
+	this._sObjName = undefined == options.sObjName ? 'oVote' : options.sObjName; // javascript object name, to run current object instance from onTimer
+	this._sSystem = options.sSystem; // current comment system
+	this._iAuthorId = options.iAuthorId; // this comment's author ID.
+    this._iObjId = options.iObjId; // this object id comments
+    this._iLikeMode = undefined == options.iLikeMode ? 0 : options.iLikeMode;
+
+    this._sActionsUrl = options.sRootUrl + 'vote.php'; // actions url address
+
+    this._sAnimationEffect = 'fade';
+    this._iAnimationSpeed = 'slow';
+    this._sSP = undefined == options.sStylePrefix ? 'bx-vote' : options.sStylePrefix;
+    this._aHtmlIds = options.aHtmlIds;
+
+    this._iSaveWidth = -1;
+
+    //--- Init stars based vote ---//
+    if(!this._iLikeMode) {
+	    var oMainStars = $('#' + this._aHtmlIds['main_stars']);
+	    if(oMainStars) {
+	    	var fRate = oMainStars.attr('bx_vote_data_rate');
+	    	var iStarWidth = this._getStarWidth(oMainStars);
+
+	    	this._getSlider(oMainStars).width(Math.round(fRate * iStarWidth));
+	    }
+    }
+}
+
+BxDolVote.prototype.toggleByPopup = function(oLink) {
+	var $this = this;
+    var oData = this._getDefaultParams();
+    oData['action'] = 'GetVotedBy';
+
+    var oPopup = $(".bx-popup-applied:visible");
+    if(oPopup.length) {
+    	oPopup.dolPopupHide();
+    	return;
+    }
+
+	this._loadingInButton(oLink, true);
+
+	jQuery.post (
+		this._sActionsUrl,
+        oData,
+        function (s) {
+			$this._loadingInButton(oLink, false);
+
+			var oPopup = $(s).hide(); 
+
+	    	$('#' + oPopup.attr('id')).remove();
+	        oPopup.prependTo('body').dolPopup({
+	        	pointer:{
+	    			el:$(oLink)
+	    		}
+	        });
+        }
+	);
+};
+
+BxDolVote.prototype.over = function (oLink)
+{
+	var oSlider = this._getSlider(oLink);
+	var iIndex = this._getButtons(oLink).index(oLink);
+
+    this._iSaveWidth = parseInt(oSlider.width());
+    oSlider.width((iIndex + 1) * this._getStarWidth(oLink));
+};
+
+BxDolVote.prototype.out = function (oLink)
+{
+	var oSlider = this._getSlider(oLink);
+
+	oSlider.width(this._iSaveWidth);
+};
+
+BxDolVote.prototype.vote = function (oLink, iValue)
+{
+    var $this = this;
+    var oParams = this._getDefaultParams();
+    oParams['action'] = 'Vote';
+    oParams['value'] = iValue;
+
+    $.post(
+    	this._sActionsUrl,
+    	oParams,
+    	function(oData) {
+    		if(oData && oData.msg != undefined)
+                alert(oData.msg);
+
+    		if(oData && oData.code != 0)
+                return;
+
+    		if(!$this._iLikeMode)
+    			$this._iSaveWidth = Math.round(oData.rate * $this._getStarWidth(oLink));
+
+            var oCounter = $this._getCounter(oLink);
+            if(oCounter)
+            	oCounter.html(oData.countf);
+        },
+        'json'
+    );
+};
+
+BxDolVote.prototype._getButtons = function(oElement) {
+	if($(oElement).hasClass(this._sSP))
+		return $(oElement).find('.' + this._sSP + '-button');
+	else
+		return $(oElement).parents('.' + this._sSP + ':first').find('.' + this._sSP + '-button');
+};
+
+BxDolVote.prototype._getSlider = function(oElement) {
+	if($(oElement).hasClass(this._sSP))
+		return $(oElement).find('.' + this._sSP + '-slider');
+	else
+		return $(oElement).parents('.' + this._sSP + ':first').find('.' + this._sSP + '-slider');
+};
+
+BxDolVote.prototype._getStarWidth = function(oElement) {
+	var oSlider = this._getSlider(oElement);
+	return oSlider.find('.sys-icon').width();
+};
+
+BxDolVote.prototype._getCounter = function(oElement) {
+	if(this._aHtmlIds['counter'] && this._aHtmlIds['counter'].length > 0)
+		return $('#' + this._aHtmlIds['counter']);
+
+	if($(oElement).hasClass(this._sSP))
+		return $(oElement).find('.' + this._sSP + '-counter span');
+	else 
+		return $(oElement).parents('.' + this._sSP + ':first').find('.' + this._sSP + '-counter span');
+};
+
+BxDolVote.prototype._loadingInButton = function(e, bShow) {
+	if($(e).length)
+		bx_loading_btn($(e), bShow);
+	else
+		bx_loading($('body'), bShow);	
+};
+
+BxDolVote.prototype._getDefaultParams = function() {
+	var oDate = new Date();
+    return {
+        sys: this._sSystem,
+        id: this._iObjId,
+        _t: oDate.getTime()
+    };
+};

+ 0 - 87
inc/js/classes/BxDolVoting.js

@@ -1,87 +0,0 @@
-/**
- * @package     Dolphin Core
- * @copyright   Copyright (c) BoonEx Pty Limited - http://www.boonex.com/
- * @license     CC-BY - http://creativecommons.org/licenses/by/3.0/
- */
-
-function BxDolVoting (sUrl, sSystem, iObjId, sId, sIdSlider, iSize, iMax)
-{
-    this._sUrl = sUrl;
-    this._sSystem = sSystem;
-    this._iObjId = iObjId;
-    this._sId = sId;
-    this._sIdSlider = sIdSlider;
-    this._iSize = iSize;
-    this._iMax = iMax;
-    this._iSaveWidth = -1;
-}
-
-BxDolVoting.prototype.over = function (i)
-{
-    var e = this._e(this._sIdSlider)
-    this._iSaveWidth = parseInt(e.style.width);
-    e.style.width = i*this._iSize + 'px';
-}
-
-BxDolVoting.prototype.setRate = function (fRate)
-{
-    var e = this._e(this._sIdSlider);
-    e.style.width = fRate*this._iSize + 'px';
-}
-
-BxDolVoting.prototype.setCount = function (iCount)
-{
-    var e = this._e(this._sId);
-    var eb = e.getElementsByTagName('b')[0];
-    if (eb != undefined) {
-        var a = eb.innerHTML.match(/(\d+)/);
-        eb.innerHTML = eb.innerHTML.replace(a[1], iCount);
-    }
-}
-
-BxDolVoting.prototype.out = function ()
-{
-    var e = this._e(this._sIdSlider)
-    e.style.width = parseInt(this._iSaveWidth) + 'px';
-}
-
-BxDolVoting.prototype.vote = function (i)
-{
-    var $this = this;
-    var h = function (s)
-    {
-        if (!s.length)
-        {
-            $this.onvotefail();
-            return;
-        }
-        var a = s.match(/([0-9\.]+),([0-9\.]+)/);
-        $this._iSaveWidth = i*$this._iSize;
-        $this.setRate(i);
-        $this.setCount(a[2]);
-        $this.onvote(a[1], a[2]);
-    }
-
-    jQuery.post(this._sUrl+'vote.php?vote_send_result='+i+'&id='+this._iObjId+'&sys='+this._sSystem, h);
-}
-
-BxDolVoting.prototype.onvote = function (fRate, iCount)
-{
-
-}
-
-BxDolVoting.prototype.onvotefail = function ()
-{
-
-}
-
-BxDolVoting.prototype._e = function (s)
-{
-    return document.getElementById(s);
-}
-
-
-BxDolVoting.prototype.sendRequest = function (sUrl, h)
-{
-    jQuery.get(sUrl, h);
-}

+ 21 - 22
install/sql/v70.sql

@@ -910,23 +910,21 @@ CREATE TABLE `sys_transactions` (
 --
 --
 
 
 CREATE TABLE `sys_objects_vote` (
 CREATE TABLE `sys_objects_vote` (
-  `ID` int(10) unsigned NOT NULL auto_increment,
-  `ObjectName` varchar(50) NOT NULL,
-  `TableRating` varchar(50) NOT NULL,
-  `TableTrack` varchar(50) NOT NULL,
-  `RowPrefix` varchar(20) NOT NULL,
-  `MaxVotes` smallint(2) NOT NULL,
-  `PostName` varchar(50) NOT NULL,
-  `IsDuplicate` varchar(80) NOT NULL,
-  `IsOn` smallint(1) NOT NULL,
-  `className` varchar(50) NOT NULL default '',
-  `classFile` varchar(100) NOT NULL default '',
-  `TriggerTable` varchar(32) NOT NULL,
-  `TriggerFieldRate` varchar(32) NOT NULL,
-  `TriggerFieldRateCount` varchar(32) NOT NULL,
-  `TriggerFieldId` varchar(32) NOT NULL,
-  `OverrideClassName` varchar(32) NOT NULL,
-  `OverrideClassFile` varchar(256) NOT NULL,
+  `ID` int(11) unsigned NOT NULL auto_increment,
+  `Name` varchar(50) NOT NULL default '',
+  `TableMain` varchar(50) NOT NULL default '',
+  `TableTrack` varchar(50) NOT NULL default '',
+  `PostTimeout` int(11) NOT NULL default '0',
+  `MinValue` tinyint(4) NOT NULL default '1',
+  `MaxValue` tinyint(4) NOT NULL default '5',
+  `IsUndo` tinyint(1) NOT NULL default '0',
+  `IsOn` tinyint(1) NOT NULL default '1',
+  `TriggerTable` varchar(32) NOT NULL default '',
+  `TriggerFieldId` varchar(32) NOT NULL default '',
+  `TriggerFieldRate` varchar(32) NOT NULL default '',
+  `TriggerFieldRateCount` varchar(32) NOT NULL default '',
+  `ClassName` varchar(32) NOT NULL default '',
+  `ClassFile` varchar(256) NOT NULL default '',
   PRIMARY KEY  (`ID`)
   PRIMARY KEY  (`ID`)
 ) ENGINE=MyISAM  DEFAULT CHARSET=utf8;
 ) ENGINE=MyISAM  DEFAULT CHARSET=utf8;
 
 
@@ -2869,8 +2867,8 @@ INSERT INTO `sys_objects_menu` (`object`, `title`, `set_name`, `module`, `templa
 ('sys_add_content', '_sys_menu_title_add_content', 'sys_add_content_links', 'system', 4, 0, 1, '', ''),
 ('sys_add_content', '_sys_menu_title_add_content', 'sys_add_content_links', 'system', 4, 0, 1, '', ''),
 ('sys_account_settings', '_sys_menu_title_account_settings', 'sys_account_settings', 'system', 6, 0, 1, '', ''),
 ('sys_account_settings', '_sys_menu_title_account_settings', 'sys_account_settings', 'system', 6, 0, 1, '', ''),
 ('sys_profiles_create', '_sys_menu_title_profiles_create', 'sys_profiles_create', 'system', 4, 0, 1, '', ''),
 ('sys_profiles_create', '_sys_menu_title_profiles_create', 'sys_profiles_create', 'system', 4, 0, 1, '', ''),
-('sys_cmts_item_manage', '_sys_menu_title_cmts_item_manage', 'sys_cmts_item_manage', 'system', 6, 0, 1, 'BxTemplMenuCmts', ''),
-('sys_cmts_item_actions', '_sys_menu_title_cmts_item_actions', 'sys_cmts_item_actions', 'system', 10, 0, 1, 'BxTemplMenuCmts', '');
+('sys_cmts_item_manage', '_sys_menu_title_cmts_item_manage', 'sys_cmts_item_manage', 'system', 6, 0, 1, 'BxTemplCmtsMenu', ''),
+('sys_cmts_item_actions', '_sys_menu_title_cmts_item_actions', 'sys_cmts_item_actions', 'system', 10, 0, 1, 'BxTemplCmtsMenu', '');
 
 
 CREATE TABLE IF NOT EXISTS `sys_menu_sets` (
 CREATE TABLE IF NOT EXISTS `sys_menu_sets` (
   `set_name` varchar(32) NOT NULL,
   `set_name` varchar(32) NOT NULL,
@@ -2948,10 +2946,11 @@ INSERT INTO `sys_menu_items`(`set_name`, `module`, `name`, `title_system`, `titl
 ('sys_cmts_item_manage', 'system', 'item-delete', '_sys_menu_item_title_system_cmts_item_delete', '_sys_menu_item_title_cmts_item_delete', 'javascript:void(0)', 'javascript:{js_object}.cmtRemove(this, {content_id})', '_self', 'remove', '', 2147483647, 1, 0, 0);
 ('sys_cmts_item_manage', 'system', 'item-delete', '_sys_menu_item_title_system_cmts_item_delete', '_sys_menu_item_title_cmts_item_delete', 'javascript:void(0)', 'javascript:{js_object}.cmtRemove(this, {content_id})', '_self', 'remove', '', 2147483647, 1, 0, 0);
 
 
 -- comment actions menu
 -- comment actions menu
+-- TODO: Remove Minus and replace Plus with simply Rate 
 INSERT INTO `sys_menu_items`(`set_name`, `module`, `name`, `title_system`, `title`, `link`, `onclick`, `target`, `icon`, `submenu_object`, `visible_for_levels`, `active`, `copyable`, `order`) VALUES 
 INSERT INTO `sys_menu_items`(`set_name`, `module`, `name`, `title_system`, `title`, `link`, `onclick`, `target`, `icon`, `submenu_object`, `visible_for_levels`, `active`, `copyable`, `order`) VALUES 
-('sys_cmts_item_actions', 'system', 'item-reply', '_sys_menu_item_title_system_cmts_item_reply', '_sys_menu_item_title_cmts_item_reply', 'javascript:void(0)', 'javascript:{js_object}.toggleReply(this, {content_id})', '_self', 'reply', '', 2147483647, 1, 0, 0),
-('sys_cmts_item_actions', 'system', 'item-rate-plus', '_sys_menu_item_title_system_cmts_item_rate_plus', '_sys_menu_item_title_cmts_item_rate_plus', 'javascript:void(0)', 'javascript:{js_object}.cmtRate(this, {content_id}, 1)', '_self', 'plus', '', 2147483647, 1, 0, 0),
-('sys_cmts_item_actions', 'system', 'item-rate-minus', '_sys_menu_item_title_system_cmts_item_rate_minus', '_sys_menu_item_title_cmts_item_rate_minus', 'javascript:void(0)', 'javascript:{js_object}.cmtRate(this, {content_id}, -1)', '_self', 'minus', '', 2147483647, 1, 0, 0);
+('sys_cmts_item_actions', 'system', 'item-rate-plus', '_sys_menu_item_title_system_cmts_item_rate_plus', '_sys_menu_item_title_cmts_item_rate_plus', 'javascript:void(0)', 'javascript:{js_object}.cmtRate(this, {content_id}, 1)', '_self', 'plus', '', 2147483647, 1, 0, 1),
+('sys_cmts_item_actions', 'system', 'item-rate-minus', '_sys_menu_item_title_system_cmts_item_rate_minus', '_sys_menu_item_title_cmts_item_rate_minus', 'javascript:void(0)', 'javascript:{js_object}.cmtRate(this, {content_id}, -1)', '_self', 'minus', '', 2147483647, 0, 0, 0);
+('sys_cmts_item_actions', 'system', 'item-reply', '_sys_menu_item_title_system_cmts_item_reply', '_sys_menu_item_title_cmts_item_reply', 'javascript:void(0)', 'javascript:{js_object}.toggleReply(this, {content_id})', '_self', 'reply', '', 2147483647, 1, 0, 2),
 
 
 -- --------------------------------------------------------
 -- --------------------------------------------------------
 
 

+ 3 - 6
modules/boonex/english/data/langs/system.xml

@@ -1,6 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
 <?xml version="1.0" encoding="utf-8"?>
 <resources name="en" flag="en" title="English">
 <resources name="en" flag="en" title="English">
-	<string name="_{0} votes"><![CDATA[{0} votes]]></string>
 	<string name="_add"><![CDATA[add]]></string>
 	<string name="_add"><![CDATA[add]]></string>
 	<string name="_bottom_text"><![CDATA[2002-{0}. Product of <a class="bottom_text" href="http://www.boonex.com/">BoonEx Group</a>.]]></string>
 	<string name="_bottom_text"><![CDATA[2002-{0}. Product of <a class="bottom_text" href="http://www.boonex.com/">BoonEx Group</a>.]]></string>
 	<string name="_copyright"><![CDATA[&copy; {0} Company]]></string>
 	<string name="_copyright"><![CDATA[&copy; {0} Company]]></string>
@@ -1156,7 +1155,6 @@ Please click "Continue" below to navigate to the home page of the site.]]></stri
 	<string name="_You must agree with terms of use"><![CDATA[You must agree with terms of use]]></string>
 	<string name="_You must agree with terms of use"><![CDATA[You must agree with terms of use]]></string>
 	<string name="_There_are_no_comments_yet"><![CDATA[There are no comments yet]]></string>
 	<string name="_There_are_no_comments_yet"><![CDATA[There are no comments yet]]></string>
 	<string name="_error occured"><![CDATA[Error occurred]]></string>
 	<string name="_error occured"><![CDATA[Error occurred]]></string>
-	<string name="_Duplicate vote"><![CDATA[Duplicate vote]]></string>
 	<string name="_No such comment"><![CDATA[No such comment]]></string>
 	<string name="_No such comment"><![CDATA[No such comment]]></string>
 	<string name="_buried"><![CDATA[buried]]></string>
 	<string name="_buried"><![CDATA[buried]]></string>
 	<string name="_toggle"><![CDATA[toggle]]></string>
 	<string name="_toggle"><![CDATA[toggle]]></string>
@@ -1171,6 +1169,7 @@ Please click "Continue" below to navigate to the home page of the site.]]></stri
 	<string name="_N_replies"><![CDATA[<span>{0}</span> replies]]></string>
 	<string name="_N_replies"><![CDATA[<span>{0}</span> replies]]></string>
 	<string name="_N_comments"><![CDATA[<span>{0}</span> comments]]></string>
 	<string name="_N_comments"><![CDATA[<span>{0}</span> comments]]></string>
 	<string name="_Comment_to_this_comment"><![CDATA[Comment]]></string>
 	<string name="_Comment_to_this_comment"><![CDATA[Comment]]></string>
+
 	<string name="_cmt_display_flat"><![CDATA[Flat]]></string>
 	<string name="_cmt_display_flat"><![CDATA[Flat]]></string>
 	<string name="_cmt_display_threaded"><![CDATA[Threaded]]></string>
 	<string name="_cmt_display_threaded"><![CDATA[Threaded]]></string>
 	<string name="_cmt_browse_tail"><![CDATA[Newest]]></string>
 	<string name="_cmt_browse_tail"><![CDATA[Newest]]></string>
@@ -1186,6 +1185,8 @@ Please click "Continue" below to navigate to the home page of the site.]]></stri
 	<string name="_cmt_close_attached_image"><![CDATA[Close]]></string>
 	<string name="_cmt_close_attached_image"><![CDATA[Close]]></string>
 	<string name="_cmt_err_cannot_perform_action"><![CDATA[Cannot perform action. Please report.]]></string>
 	<string name="_cmt_err_cannot_perform_action"><![CDATA[Cannot perform action. Please report.]]></string>
 	<string name="_cmt_err_duplicate"><![CDATA[Duplicate vote.]]></string>
 	<string name="_cmt_err_duplicate"><![CDATA[Duplicate vote.]]></string>
+	<string name="_vote_do_like"><![CDATA[Plus]]></string>
+	<string name="_vote_err_duplicate_vote"><![CDATA[Duplicate vote]]></string>
 	<string name="_Reply_to_this_comment"><![CDATA[Reply]]></string>
 	<string name="_Reply_to_this_comment"><![CDATA[Reply]]></string>
 	<string name="_Add Your Comment"><![CDATA[Comment]]></string>
 	<string name="_Add Your Comment"><![CDATA[Comment]]></string>
 	<string name="_load_more_comments_head"><![CDATA[See Newer Comments...]]></string>
 	<string name="_load_more_comments_head"><![CDATA[See Newer Comments...]]></string>
@@ -3553,10 +3554,6 @@ More info about URI DNSBL: <br />
     <string name="_sys_form_comment_input_caption_system_cmt_image"><![CDATA[Image]]></string>
     <string name="_sys_form_comment_input_caption_system_cmt_image"><![CDATA[Image]]></string>
     <string name="_sys_form_comment_input_caption_system_cmt_submit"><![CDATA[Post]]></string>
     <string name="_sys_form_comment_input_caption_system_cmt_submit"><![CDATA[Post]]></string>
     <string name="_sys_form_comment_input_submit"><![CDATA[Post]]></string>
     <string name="_sys_form_comment_input_submit"><![CDATA[Post]]></string>
-    <string name=""><![CDATA[]]></string>
-    <string name=""><![CDATA[]]></string>
-    <string name=""><![CDATA[]]></string>
-    <string name=""><![CDATA[]]></string>
 
 
     <string name="_sys_page_lang_block_about"><![CDATA[This site is powered by BoonEx Dolphin. The rest is a mystery.]]></string>
     <string name="_sys_page_lang_block_about"><![CDATA[This site is powered by BoonEx Dolphin. The rest is a mystery.]]></string>
 
 

+ 5 - 5
modules/boonex/uni/data/template/system/scripts/BxTemplVotingView.php → modules/boonex/uni/data/template/system/scripts/BxTemplVoteView.php

@@ -6,16 +6,16 @@
  */
  */
 defined('BX_DOL') or die('hack attempt');
 defined('BX_DOL') or die('hack attempt');
 
 
-bx_import('BxBaseVotingView');
+bx_import('BxBaseVoteView');
 
 
 /**
 /**
- * @see BxDolVoting
+ * @see BxDolVote
  */
  */
-class BxTemplVotingView extends BxBaseVotingView
+class BxTemplVoteView extends BxBaseVoteView
 {
 {
-    function BxTemplVotingView( $sSystem, $iId, $iInit = 1 )
+    function __construct($sSystem, $iId, $iInit = 1)
     {
     {
-        BxBaseVotingView::BxBaseVotingView( $sSystem, $iId, $iInit );
+		parent::__construct($sSystem, $iId, $iInit);
     }
     }
 }
 }
 
 

+ 1 - 0
template/bx_icon.html

@@ -0,0 +1 @@
+<i class="sys-icon __name__"></i>

+ 4 - 0
template/css/menu.css

@@ -22,6 +22,10 @@ ul.bx-menu-hor {
     text-decoration:none;
     text-decoration:none;
 }
 }
 
 
+.bx-menu-hor-inline li a {
+	display:inline;
+}
+
 .bx-menu-hor li.bx-menu-tab-active a {
 .bx-menu-hor li.bx-menu-tab-active a {
     color:#000;
     color:#000;
 }
 }

+ 76 - 0
template/css/vote.css

@@ -0,0 +1,76 @@
+/*--- Comment Plused By ---*/
+div.bx-vote-by-list {}
+div.bx-vote-by-list-cnt {
+	max-height: 200px;
+	min-width: 225px;
+	overflow: auto;
+}
+div.bx-vote-by-list div.bx-persons-unit {
+	float: none;
+	margin-right: 0px;
+	margin-bottom: 0px;
+}
+    
+/*--- Likes based Element Styles ---*/
+.bx-vote-likes .bx-vote-element-holder,
+.bx-vote-likes .bx-vote-counter-holder {
+	line-height: 36px;
+	line-height: 2.2rem;
+}
+div.bx-vote-likes div.bx-vote-element-holder,
+div.bx-vote-likes div.bx-vote-counter-holder {
+	position: relative;
+	float: left;
+}
+
+
+/*--- Stars based Element Styles ---*/
+.bx-vote-stars .bx-vote-element-holder,
+.bx-vote-stars .bx-vote-counter-holder {
+	line-height: 16px;
+	line-height: 1rem;
+}
+
+div.bx-vote-stars div.bx-vote-element-holder,
+div.bx-vote-stars div.bx-vote-counter-holder {
+	position: relative;
+	float: left;
+}
+
+/*--- Stars Styles ---*/
+div.bx-vote-element {
+	position: relative;
+}
+span.bx-vote-stars div.bx-vote-element {
+	display: inline-block;
+}
+div.bx-vote-underlay {}
+div.bx-vote-slider {
+    position: absolute;
+	z-index: 1;
+    top: 0px;
+    left: 0px;
+    white-space: nowrap;
+    overflow: hidden;
+}
+i.bx-vote-star,
+span.bx-vote-star {
+	display: inline-block;
+	height: 16px;
+	height: 1rem;
+	width: 16px;
+    width: 1rem;	
+    margin: 0;
+    padding: 0;
+    text-align: center;
+	color: #3e8685;
+}
+div.bx-vote-buttons {
+    position: absolute;
+	z-index: 2;
+	top: 0px;
+	left: 0px;
+}
+div.bx-vote-buttons a:hover {
+	text-decoration: none;
+}

+ 1 - 0
template/menu_inline.html

@@ -6,6 +6,7 @@
 				<bx_if:image><img style="background-image:url(__icon_url__)" src="<bx_icon_url:spacer.gif />" /></bx_if:image>
 				<bx_if:image><img style="background-image:url(__icon_url__)" src="<bx_icon_url:spacer.gif />" /></bx_if:image>
 				<span>__title__</span>
 				<span>__title__</span>
 			</a>
 			</a>
+			__addon__
 		</li>
 		</li>
     </bx_repeat:menu_items>
     </bx_repeat:menu_items>
 </ul>
 </ul>

+ 2 - 0
template/scripts/BxBaseMenu.php

@@ -93,6 +93,8 @@ class BxBaseMenu extends BxDolMenu {
                 'content' => array('title' => $a['title']), 
                 'content' => array('title' => $a['title']), 
             );
             );
 
 
+            $a['addon'] = '';
+            
             $aRet[] = $a;
             $aRet[] = $a;
         }
         }
 
 

+ 280 - 0
template/scripts/BxBaseVoteView.php

@@ -0,0 +1,280 @@
+<?php
+/**
+ * @package     Dolphin Core
+ * @copyright   Copyright (c) BoonEx Pty Limited - http://www.boonex.com/
+ * @license     CC-BY - http://creativecommons.org/licenses/by/3.0/
+ */
+defined('BX_DOL') or die('hack attempt');
+
+bx_import('BxDolVote');
+bx_import('BxDolTemplate');
+
+/**
+ * @see BxDolVote
+ */
+class BxBaseVoteView extends BxDolVote
+{
+	protected $_sJsObjName;
+	protected $_sStylePrefix;
+
+	protected $_aHtmlIds;
+
+	protected $_aElementDefaults;
+
+	protected $_sTmplNameCounter;
+	protected $_sTmplNameDoVoteLikes;
+	protected $_sTmplNameDoVoteStars;
+
+    public function __construct($sSystem, $iId, $iInit = 1)
+    {
+        parent::__construct($sSystem, $iId, $iInit);
+
+		$this->_sJsObjName = 'oVote' . str_replace(' ', '', ucwords(str_replace(array('_' , '-'), array(' ', ' '), $sSystem))) . $iId;
+        $this->_sStylePrefix = 'bx-vote';
+
+        $sHtmlId = str_replace(array('_' , ' '), array('-', '-'), $sSystem) . '-' . $iId;
+        $this->_aHtmlIds = array(
+        	'main_stars' => 'bx-vote-stars-' . $sHtmlId,
+        	'main_likes' => 'bx-vote-likes-' . $sHtmlId,
+        	'counter' => 'bx-vote-counter-' . $sHtmlId,
+        	'by_popup' => 'bx-vote-by-popup-' . $sHtmlId
+        );
+
+        $this->_aElementDefaults = array(
+        	'stars' => array(
+	        	'show_do_vote_legend' => false,
+        		'show_counter' => true,
+        		'show_counter_labled' => true,
+	        ),
+	        'likes' => array(
+	        	'show_do_vote_as_button' => false,
+	        	'show_do_vote_icon' => true,
+	        	'show_do_vote_label' => false,
+        		'show_counter' => true,
+	        	'show_counter_labled' => true,
+        	)
+        );
+
+        $this->_sTmplNameCounter = 'vote_counter.html';
+        $this->_sTmplNameDoVoteLikes = 'vote_do_vote_likes.html';
+        $this->_sTmplNameDoVoteStars = 'vote_do_vote_stars.html';
+    }
+
+	public function addCssJs()
+    {
+        $oTemplate = BxDolTemplate::getInstance();
+
+        $oTemplate->addJs('BxDolVote.js');
+        $oTemplate->addCss('vote.css');
+    }
+
+	public function getJsObjectName()
+    {
+    	return $this->_sJsObjName;
+    }
+
+	public function getJsScript()
+    {
+        $this->addCssJs();
+
+        require_once(BX_DIRECTORY_PATH_PLUGINS . 'Services_JSON.php');
+        $oJson = new Services_JSON();
+
+        return BxDolTemplate::getInstance()->_wrapInTagJsCode("var " . $this->_sJsObjName . " = new BxDolVote({
+        	sObjName: '" . $this->_sJsObjName . "',
+            sSystem: '" . $this->getSystemName() . "',
+            iAuthorId: '" . $this->_getAuthorId() . "',
+            iObjId: '" . $this->getId() . "',
+            iLikeMode: " . ($this->isLikeMode() ? 1 : 0) . ",
+            sRootUrl: '" . BX_DOL_URL_ROOT . "',
+            sStylePrefix: '" . $this->_sStylePrefix . "',
+            aHtmlIds: " . $oJson->encode($this->_aHtmlIds) . ",
+    	});");
+    }
+
+    public function getJsClick()
+    {
+    	if(!$this->isLikeMode())
+    		return false;
+
+    	return $this->getJsObjectName() . '.vote(this, ' . $this->getMaxValue() . ')';
+    }
+
+    public function getCounter($aParams = array()) {
+    	$sJsObject = $this->getJsObjectName();
+
+    	$aVote = $this->_oQuery->getVote($this->getId());
+
+    	return BxDolTemplate::getInstance()->parseHtmlByName($this->_sTmplNameCounter, array(
+    		'style_prefix' => $this->_sStylePrefix,
+    		'js_object' => $sJsObject,
+			'html_id_counter' => $this->_aHtmlIds['counter'],
+			'counter' => (int)$aVote['count'] > 0 ? $this->_getLabelCounter($aVote['count']) : ''
+    	));
+    }
+
+	public function getElementBlock($aParams = array())
+    {
+    	$aParams['usage'] = BX_DOL_VOTE_USAGE_BLOCK;
+
+    	return $this->getElement($aParams);
+    }
+
+    public function getElementInline($aParams = array())
+    {
+    	$aParams['usage'] = BX_DOL_VOTE_USAGE_INLINE;
+
+    	return $this->getElement($aParams);
+    }
+
+	public function getElement($aParams = array())
+    {
+    	$sType = $this->isLikeMode() ? BX_DOL_VOTE_TYPE_LIKES : BX_DOL_VOTE_TYPE_STARS;
+
+    	$sMethodDoVote = '_getDoVote' . ucfirst($sType);
+    	if(!method_exists($this, $sMethodDoVote))
+    		return '';
+
+    	$aVote = $this->_oQuery->getVote($this->getId());
+    	$aParams = array_merge($this->_aElementDefaults[$sType], $aParams);
+
+    	$sTmplName = 'vote_element_' . (!empty($aParams['usage']) ? $aParams['usage'] : BX_DOL_VOTE_USAGE_DEFAULT) . '.html';
+    	return BxDolTemplate::getInstance()->parseHtmlByName($sTmplName, array(
+    		'style_prefix' => $this->_sStylePrefix,
+    		'html_id' => $this->_aHtmlIds['main_' . $sType],
+    		'type' => $sType,
+    		'rate' => $aVote['rate'],
+    		'count' => $aVote['count'],
+    		'do_vote' => $this->$sMethodDoVote($aParams),
+    		'bx_if:show_counter' => array(
+    			'condition' => isset($aParams['show_counter']) && $aParams['show_counter'] === true,
+    			'content' => array(
+    				'style_prefix' => $this->_sStylePrefix,
+    				'counter' => $this->getCounter()
+    			)
+    		),
+    		'script' => $this->getJsScript()
+    	));
+    }
+
+	protected function _getDoVoteStars($aParams = array())
+    {
+		$sJsObject = $this->getJsObjectName();
+    	$iMinValue = $this->getMinValue();
+    	$iMaxValue = $this->getMaxValue();
+
+    	$aVote = $this->_oQuery->getVote($this->getId());
+
+    	$aTmplVarsButtons = $aTmplVarsStars = array();
+    	for($i = $iMinValue; $i <= $iMaxValue; $i++) {
+    		$aTmplVarsStars[] = array(
+    			'style_prefix' => $this->_sStylePrefix,
+    			'value' => $i
+    		);
+
+    		$aTmplVarsLegend[] = array(
+    			'style_prefix' => $this->_sStylePrefix,
+    			'value' => $i
+    		);
+
+    		$aTmplVarsSlider[] = array(
+    			'style_prefix' => $this->_sStylePrefix
+    		);
+
+    		$aTmplVarsButtons[] = array(
+    			'style_prefix' => $this->_sStylePrefix,
+    			'js_object' => $sJsObject,
+    			'value' => $i
+    		);
+    	}
+
+    	return BxDolTemplate::getInstance()->parseHtmlByName($this->_sTmplNameDoVoteStars, array(
+    		'style_prefix' => $this->_sStylePrefix,
+    		'bx_repeat:stars' => $aTmplVarsStars,
+    		'bx_if:show_legend' => array(
+    			'condition' => isset($aParams['show_do_vote_legend']) && $aParams['show_do_vote_legend'] === true,
+    			'content' => array(
+    				'style_prefix' => $this->_sStylePrefix,
+    				'bx_repeat:legend' => $aTmplVarsLegend,
+    			)
+    		),
+    		'bx_repeat:slider' => $aTmplVarsSlider,
+    		'bx_repeat:buttons' => $aTmplVarsButtons,
+    	));
+    }
+
+    protected function _getDoVoteLikes($aParams = array())
+    {
+    	return BxDolTemplate::getInstance()->parseHtmlByName($this->_sTmplNameDoVoteLikes, array(
+    		'style_prefix' => $this->_sStylePrefix,
+    		'js_object' => $this->getJsObjectName(),
+    		'bx_if:show_as_button' => array(
+    			'condition' => isset($aParams['show_as_button']) && $aParams['show_as_button'] === true,
+    			'content' => array()
+    		),
+    		'value' => $this->getMinValue(),
+    		'do_vote' => $this->_getLabelDoLike($aParams),
+    	));
+    }
+
+	protected function _getLabelCounter($iCount)
+	{
+    	return $iCount;
+    }
+
+	protected function _getLabelDoLike($aParams = array())
+    {
+    	$sResult = '';
+    	if(isset($aParams['show_do_vote_icon']) && $aParams['show_do_vote_icon'] == true)
+    		$sResult .= BxDolTemplate::getInstance()->parseHtmlByName('bx_icon.html', array('name' => 'plus'));
+
+		if(isset($aParams['show_do_vote_label']) && $aParams['show_do_vote_label'] == true)
+			$sResult .= ($sResult != '' ? ' ' : '') . _t('_vote_do_like');
+
+    	return $sResult;
+    }
+
+	protected function _getVotedBy()
+    {
+    	$aTmplUsers = array();
+
+    	$aUserIds = $this->_oQuery->getVotedBy($this->getId());
+    	foreach($aUserIds as $iUserId) {
+    		list($sUserName, $sUserUrl, $sUserIcon, $sUserUnit) = $this->_getAuthorInfo($iUserId);
+			$aTmplUsers[] = array(
+				'style_prefix' => $this->_sStylePrefix,
+				'user_unit' => $sUserUnit
+			);
+    	}
+
+		if(empty($aTmplUsers))
+			$aTmplUsers = MsgBox(_t('_Empty'));
+
+    	$oTemplate = BxDolTemplate::getInstance();
+
+    	bx_import('BxTemplStudioFunctions');
+        $sContent = BxTemplStudioFunctions::getInstance()->transBox($oTemplate->parseHtmlByName('vote_by_list.html', array(
+    		'style_prefix' => $this->_sStylePrefix,
+    		'bx_repeat:list' => $aTmplUsers
+    	)));
+
+        return $oTemplate->parseHtmlByName('vote_by.html', array(
+        	'style_prefix' => $this->_sStylePrefix,
+        	'id' => $this->_aHtmlIds['by_popup'],
+        	'content' => $sContent
+        ));
+    }
+
+	protected function _echoResultJson($a, $isAutoWrapForFormFileSubmit = false)
+	{
+        header('Content-type: text/html; charset=utf-8');    
+
+        require_once(BX_DIRECTORY_PATH_PLUGINS . 'Services_JSON.php');
+
+        $oParser = new Services_JSON();
+        $s = $oParser->encode($a);
+        if ($isAutoWrapForFormFileSubmit && !empty($_FILES)) 
+            $s = '<textarea>' . $s . '</textarea>'; // http://jquery.malsup.com/form/#file-upload
+        echo $s;
+    }
+}

+ 0 - 104
template/scripts/BxBaseVotingView.php

@@ -1,104 +0,0 @@
-<?php
-/**
- * @package     Dolphin Core
- * @copyright   Copyright (c) BoonEx Pty Limited - http://www.boonex.com/
- * @license     CC-BY - http://creativecommons.org/licenses/by/3.0/
- */
-defined('BX_DOL') or die('hack attempt');
-
-bx_import('BxDolVoting');
-bx_import('BxDolTemplate');
-
-/**
- * @see BxDolVoting
- */
-class BxBaseVotingView extends BxDolVoting
-{
-    var $_iSizeStarBigX = 18;
-    var $_iSizeStarBigY = 16;
-    var $_iSizeStarSmallX = 11;
-    var $_iSizeStarSmallY = 15;
-
-    function BxBaseVotingView( $sSystem, $iId, $iInit = 1 )
-    {
-        BxDolVoting::BxDolVoting( $sSystem, $iId, $iInit );
-    }
-
-    function getSmallVoting ($iCanRate = 1, $iVoteRateOverride = false)
-    {
-        if ($iCanRate != 0) {
-            if (!$this->checkAction()) $iCanRate = 0;
-        }
-        return $this->getVoting($iCanRate, $this->_iSizeStarSmallX, $this->_iSizeStarSmallY, 'small', 0, true, $iVoteRateOverride);
-    }
-
-    function getManySmallVoting($iCanRate = 1, $iID = 0, $isShowCount = true, $iVoteRateOverride = false)
-    {
-        if ($iCanRate != 0) {
-            if (!$this->checkAction()) $iCanRate = 0;
-        }
-        return $this->getVoting($iCanRate, $this->_iSizeStarSmallX, $this->_iSizeStarSmallY, 'small', $iID, $isShowCount, $iVoteRateOverride);
-    }
-
-    function getBigVoting ($iCanRate = 1, $iVoteRateOverride = false)
-    {
-        if ($iCanRate != 0) {
-            if (!$this->checkAction()) $iCanRate = 0;
-        }
-        return $this->getVoting($iCanRate, $this->_iSizeStarBigX, $this->_iSizeStarBigY, 'big', 0, true, $iVoteRateOverride);
-    }
-
-    function getJustVotingElement($iCanRate, $iPossibleID = 0, $iVoteRateOverride = false)
-    {
-        return $this->getManySmallVoting($iCanRate, $iPossibleID, false, $iVoteRateOverride);
-    }
-
-    function getVoting($iCanRate, $iSizeX, $iSizeY, $sName, $iPossibleID = 0, $isShowCount = true, $iVoteRateOverride = false) {
-        $oSysTemplate = BxDolTemplate::getInstance();
-
-        $sSiteUrl = BX_DOL_URL_ROOT;
-        $iMax = $this->getMaxVote();
-        $iWidth = $iSizeX*$iMax;
-        $sSystemName = $this->getSystemName();
-        $iObjId = $iPossibleID ? $iPossibleID : $this->getId();
-        $sDivId = $this->getSystemName() . $sName;
-        if ($iPossibleID>0) {
-            $sDivId .= $iPossibleID;
-        }
-
-        $sRet = '<div class="votes_'.$sName.'" id="' . $sDivId . '">';
-
-        if ($iCanRate)
-            $sRet .= <<<EOF
-<script language="javascript">
-    var oVoting{$sDivId} = new BxDolVoting('{$sSiteUrl}', '{$sSystemName}', '{$iObjId}', '{$sDivId}', '{$sDivId}Slider', {$iSizeX}, {$iMax});
-</script>
-EOF;
-
-        $sRet .= '<div class="votes_gray_'.$sName.'" style="width:'.$iWidth.'px;">';
-
-        if ($iCanRate)
-        {
-            $sRet .= '<div class="votes_buttons">';
-            for ($i=1 ; $i<=$iMax ; ++$i)
-            {
-                $sRet .= '<a href="javascript:'.$i.';void(0);" onmouseover="oVoting'.$sDivId.'.over('.$i.');" onmouseout="oVoting'.$sDivId.'.out();" onclick="oVoting'.$sDivId.'.vote('.$i.')"><img class="votes_button_' . $sName . '" src="' . $oSysTemplate->getImageUrl('vote_star_null.gif') . '" alt="" /></a>';
-            }
-            $sRet .= '</div>';
-        }
-        $iVoteRate = (false === $iVoteRateOverride ? $this->getVoteRate() : $iVoteRateOverride);
-        $sRet .= '<div id="'.$sDivId.'Slider" class="votes_active_'.$sName.'" style="width:'.round($iVoteRate*($iMax ? $iWidth/$iMax : 0)).'px;"></div>';
-        $sRet .= '</div>';
-        if ($isShowCount)
-            $sRet .= '<b>'.$this->getVoteCount(). ' ' . _t('_votes') . '</b>';
-        $sRet .= '<div class="clear_both"></div>';
-        $sRet .= '</div>';
-
-        return $sRet;
-    }
-
-    function getExtraJs () {
-        BxDolTemplate::getInstance()->addJs('BxDolVoting.js');
-    }
-}
-

+ 1 - 0
template/vote_by.html

@@ -0,0 +1 @@
+<div id="__id__" class="__style_prefix__-by-popup" style="display:none;">__content__</div>

+ 9 - 0
template/vote_by_list.html

@@ -0,0 +1,9 @@
+<div class="__style_prefix__-by-list bx-def-padding-sec">
+	<div class="__style_prefix__-by-list-cnt">
+		<div class="__style_prefix__-by-items">
+			<bx_repeat:list>
+				<div class="__style_prefix__-by-item bx-def-padding-sec">__user_unit__</div>
+			</bx_repeat:list>
+		</div>
+	</div>
+</div>

+ 1 - 0
template/vote_counter.html

@@ -0,0 +1 @@
+<a id="__html_id_counter__" class="__style_prefix__-counter" href="javascript:void(0)" onclick="__js_object__.toggleByPopup(this)">__counter__</a>

+ 1 - 0
template/vote_do_vote_likes.html

@@ -0,0 +1 @@
+<a class="__style_prefix__-do-vote<bx_if:show_as_button> bx-btn</bx_if:show_as_button>" href="javascript:void(0)" onclick="javascript:__js_object__.vote(this, __value__)">__do_vote__</a>

+ 16 - 0
template/vote_do_vote_stars.html

@@ -0,0 +1,16 @@
+<div class="__style_prefix__-element">
+	<div class="__style_prefix__-underlay">
+		<bx_repeat:stars><i class="__style_prefix__-star sys-icon star-o"></i></bx_repeat:stars>
+	</div>
+	<bx_if:show_legend>
+		<div class="__style_prefix__-legend bx-def-font-small">
+			<bx_repeat:legend><span class="bx-vote-star">__value__</span></bx_repeat:legend>
+		</div>
+	</bx_if:show_legend>
+	<div class="__style_prefix__-slider">
+		<bx_repeat:slider><i class="__style_prefix__-star sys-icon star"></i></bx_repeat:slider>
+	</div>
+	<div class="__style_prefix__-buttons">
+		<bx_repeat:buttons><a class="__style_prefix__-button" href="javascript:void(0);" onmouseover="__js_object__.over(this);" onmouseout="__js_object__.out(this);" onclick="__js_object__.vote(this, __value__)"><i class="__style_prefix__-star sys-icon">&#61446;</i></a></bx_repeat:buttons>
+	</div>
+</div>

+ 7 - 0
template/vote_element_block.html

@@ -0,0 +1,7 @@
+<div id="__html_id__" class="__style_prefix__ __style_prefix__-__type__ bx-clearfix" bx_vote_data_rate="__rate__" bx_vote_data_count="__count__">
+	<div class="__style_prefix__-element-holder">__do_vote__</div>
+	<bx_if:show_counter>
+		<div class="__style_prefix__-counter-holder bx-def-margin-sec-left">__counter__</div>
+	</bx_if:show_counter>
+</div>
+__script__

+ 4 - 0
template/vote_element_inline.html

@@ -0,0 +1,4 @@
+<span id="__html_id__" class="__style_prefix__ __style_prefix__-__type__" bx_vote_data_rate="__rate__" bx_vote_data_count="__count__">
+	<span class="__style_prefix__-element-holder">__do_vote__</span><bx_if:show_counter><span class="__style_prefix__-counter-holder bx-def-margin-sec-left">__counter__</span></bx_if:show_counter>
+</span>
+__script__

+ 16 - 15
vote.php

@@ -6,23 +6,24 @@
  */
  */
 
 
 require_once('./inc/header.inc.php');
 require_once('./inc/header.inc.php');
+require_once(BX_DIRECTORY_PATH_INC . "params.inc.php");
+require_once(BX_DIRECTORY_PATH_INC . "design.inc.php");
 
 
-bx_import("BxDolVoting");
+bx_import('BxDolAcl');
+bx_import('BxDolLanguages');
 
 
-$aSystems =& BxDolVoting::getSystems ();
+check_logged();
 
 
-$sSys = isset($_GET['sys']) ? bx_process_input($_GET['sys']) : false;
-$iId = isset($_GET['id']) ? bx_process_input($_GET['id'], BX_DATA_INT) : 0;
+$sSys = isset($_REQUEST['sys']) ? bx_process_input($_REQUEST['sys']) : false;
+$iObjectId = isset($_REQUEST['id']) ? bx_process_input($_REQUEST['id'], BX_DATA_INT) : 0;
+$sAction = isset($_REQUEST['action']) && preg_match ('/^[A-Za-z_-]+$/', $_REQUEST['action']) ? bx_process_input($_REQUEST['action']) : '';
 
 
-if ($sSys && isset($aSystems[$sSys])) {
-
-    if ($aSystems[$sSys]['override_class_name']) {
-        require_once (BX_DIRECTORY_PATH_ROOT . $aSystems[$sSys]['override_class_file']);
-        $sClassName = $aSystems[$sSys]['override_class_name'];
-        new $sClassName($sSys, $iId);
-    } else {
-        new BxDolVoting($sSys, $iId);
-    }
-
-}
+bx_import("BxDolVote");
+$oVote = BxDolVote::getObjectInstance($sSys, $iObjectId, true);
 
 
+if ($oVote && $sSys && $iObjectId && $sAction) {
+    header('Content-Type: text/html; charset=utf-8');
+    $sMethod = 'action' . ucfirst($sAction);
+    if(method_exists($oVote, $sMethod))
+    	echo $oVote->$sMethod();
+}