RomanL 6 лет назад
Родитель
Сommit
241948a41f

+ 76 - 43
inc/classes/BxDolFavorite.php

@@ -25,6 +25,7 @@ define('BX_DOL_FAVORITE_USAGE_DEFAULT', BX_DOL_FAVORITE_USAGE_BLOCK);
  * @code
  *  `name` - system name, it is better to use unique module prefix here, lowercase and all spaces are underscored
  *  `table_track` - table to track favorites
+ *  `table_lists` - table with lists 
  *  `is_on` - is the system activated
  *  `trigger_table` - table where you need to update favorites field
  *  `trigger_field_id` - table field id to unique determine object
@@ -59,6 +60,10 @@ class BxDolFavorite extends BxDolObject
         $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_favorite';
+        $this->_sFormDisplayAdd = 'sys_favorite_add';
+        $this->_sFormDisplayListEdit = 'sys_favorite_list_edit';
     }
 
    /**
@@ -89,6 +94,22 @@ class BxDolFavorite extends BxDolObject
         return ($GLOBALS['bxDolClasses'][$sKey] = $o);
     }
 
+    public function getConditionsTrack($sMainTable, $sMainField, $iAuthorId = 0, $iListId = 0)
+    {
+        $aConditions = parent::getConditionsTrack($sMainTable, $sMainField, $iAuthorId);
+        if (empty($aConditions) || !isset($this->_aSystem['table_lists']) || $this->_aSystem['table_lists'] == '')
+            return $aConditions;
+        
+        $sTableTrack = isset($this->_aSystem['table_track']) ? $this->_aSystem['table_track'] : '';
+        $aConditions['restriction']['objects_' . $this->_sSystem . '_list'] = array(
+            'value' => $iListId,
+            'field' => 'list_id',
+            'operator' => '=',
+            'table' => $sTableTrack,
+        );
+        return $aConditions;
+    }
+    
     public static function &getSystems()
     {
         $sKey = 'bx_dol_cache_memory_favorite_systems';
@@ -99,6 +120,7 @@ class BxDolFavorite extends BxDolObject
                     `id` as `id`,
                     `name` AS `name`,
                     `table_track` AS `table_track`,
+                    `table_lists` AS `table_lists`,
                     `is_on` AS `is_on`,
                     `is_undo` AS `is_undo`,
                     `is_public` AS `is_public`,
@@ -128,7 +150,43 @@ class BxDolFavorite extends BxDolObject
      */
     public function actionFavorite()
     {
-        return echoJson($this->_doFavorite());
+        return echoJson($this->_getFavorite());
+    }
+    
+    public function actionEditList()
+    {
+        $iListId = null;
+        if(!bx_get('list_id'))
+            return false;
+        
+        $iListId = (int) bx_get('list_id');
+        $aList = $this->_oQuery->getList(array('type' => 'id', 'list_id' => $iListId));
+         
+        if ($this->isAllowedEditList($aList['author_id'])){
+            return echoJson($this->_getEditList($aList));
+        }
+        
+        return false;
+    }
+    
+    public function actionDeleteList()
+    {
+        $iListId = null;
+        if(!bx_get('list_id'))
+            return false;
+        
+        $iListId = (int) bx_get('list_id');
+        $aList = $this->_oQuery->getList(array('type' => 'id', 'list_id' => $iListId));
+        
+        $oModule = BxDolModule::getInstance($this->_aSystem["name"]);
+        $CNF = $oModule->_oConfig->CNF;    
+        
+        if ($this->isAllowedEditList($aList['author_id'])){
+            $this->_oQuery->deleteList($iListId);
+            return echoJson(array('redirect' => BxDolPermalinks::getInstance()->permalink('page.php?i=' . $CNF['URI_AUTHOR_ENTRIES'] . '&profile_id=' . $aList['author_id'])));
+        }
+        
+        return false;
     }
 
 	public function actionGetFavoritedBy()
@@ -152,6 +210,17 @@ class BxDolFavorite extends BxDolObject
 
         return $this->checkAction('favorite', $isPerformAction);
     }
+    
+    public function isAllowedEditList($iAuthorId, $isPerformAction = false)
+    {
+        if(isAdmin())
+            return true;
+        
+        if ($iAuthorId == bx_get_logged_profile_id())
+            return true;
+        
+        return false;
+    }
 
 	public function msgErrAllowedFavorite()
     {
@@ -190,48 +259,7 @@ class BxDolFavorite extends BxDolObject
 	/**
      * Internal functions
      */
-	protected function _doFavorite()
-    {
-        if (!$this->isEnabled())
-           return array('code' => 1, 'message' => _t('_favorite_err_not_enabled'));
-
-        $iObjectId = $this->getId();
-        $iObjectAuthorId = $this->_oQuery->getObjectAuthorId($iObjectId);
-        $iAuthorId = $this->_getAuthorId();
-
-        $bUndo = $this->isUndo();
-        $bPerformed = $this->isPerformed($iObjectId, $iAuthorId);
-        $bPerformUndo = $bPerformed && $bUndo ? true : false;
-
-        if(!$bPerformUndo && !$this->isAllowedFavorite())
-            return array('code' => 2, 'message' => $this->msgErrAllowedFavorite());
-
-        if($bPerformed && !$bUndo)
-        	return array('code' => 3, 'message' => _t('_favorite_err_duplicate_favorite'));
-
-        if(!$this->_oQuery->{($bPerformUndo ? 'un' : '') . 'doFavorite'}($iObjectId, $iAuthorId))
-            return array('code' => 4, 'message' => _t('_favorite_err_cannot_perform_action'));
-
-        if(!$bPerformUndo)
-            $this->isAllowedFavorite(true);
-
-        $this->_triggerValue($bPerformUndo ? -1 : 1);
-
-        bx_alert($this->_sSystem, ($bPerformUndo ? 'un' : '') . 'favorite', $iObjectId, $iAuthorId, array('favorite_author_id' => $iAuthorId, 'object_author_id' => $iObjectAuthorId));
-        bx_alert('favorite', ($bPerformUndo ? 'un' : '') . 'do', 0, $iAuthorId, array('object_system' => $this->_sSystem, 'object_id' => $iObjectId, 'object_author_id' => $iObjectAuthorId));
-
-        $aFavorite = $this->_oQuery->getFavorite($iObjectId);
-        return array(
-        	'eval' => $this->getJsObjectName() . '.onFavorite(oData, oElement)',
-        	'code' => 0, 
-        	'count' => $aFavorite['count'],
-        	'countf' => (int)$aFavorite['count'] > 0 ? $this->_getCounterLabel($aFavorite['count']) : '',
-            'label_icon' => $this->_getIconDoFavorite(!$bPerformed),
-            'label_title' => _t($this->_getTitleDoFavorite(!$bPerformed)),
-            'disabled' => !$bPerformed && !$bUndo
-        );
-    }
-
+	
     protected function _getIconDoFavorite($bPerformed)
     {
     	return $bPerformed && $this->isUndo() ?  'far fa-bookmark' : 'fas fa-bookmark';
@@ -241,6 +269,11 @@ class BxDolFavorite extends BxDolObject
     {
     	return $bPerformed && $this->isUndo() ? '_favorite_do_unfavorite' : '_favorite_do_favorite';
     }
+    
+    protected function _getFormObject($sDisplayName)
+    {
+        return BxDolForm::getObjectInstance($this->_sFormObject, $sDisplayName);
+    }
 }
 
 /** @} */

+ 87 - 13
inc/classes/BxDolFavoriteQuery.php

@@ -12,10 +12,15 @@
  */
 class BxDolFavoriteQuery extends BxDolObjectQuery
 {
+    protected $_sTableLists;
+    
     public function __construct(&$oModule)
     {
         parent::__construct($oModule);
 
+        $aSystem = $this->_oModule->getSystemInfo();
+        $this->_sTableLists = isset($aSystem['table_lists']) ? $aSystem['table_lists'] : '';
+        
         $this->_sMethodGetEntry = 'getFavorite';
     }
 
@@ -36,25 +41,94 @@ class BxDolFavoriteQuery extends BxDolObjectQuery
         return array('count' => $this->getObjectCount($iObjectId));
     }
 
-    public function doFavorite($iObjectId, $iAuthorId)
+    public function clearFavorite($iObjectId, $iAuthorId)
     {
-        $sQuery = $this->prepare("SELECT `date` FROM `{$this->_sTableTrack}` WHERE `object_id` = ? AND `author_id` = ? LIMIT 1", $iObjectId, $iAuthorId);
-        if((int)$this->getOne($sQuery) > 0)
-        	return true;
-
-        $sQuery = $this->prepare("INSERT IGNORE INTO `{$this->_sTableTrack}` SET `object_id` = ?, `author_id` = ?, `date` = ?", $iObjectId, $iAuthorId, time());
+        $sQuery = $this->prepare("DELETE FROM `{$this->_sTableTrack}` WHERE `object_id` = ? AND `author_id` = ?", $iObjectId, $iAuthorId);
         return (int)$this->query($sQuery) > 0;
     }
-
-	public function undoFavorite($iObjectId, $iAuthorId)
+    
+    public function doFavorite($iObjectId, $iAuthorId, $iListId)
     {
-        $sQuery = $this->prepare("SELECT `date` FROM `{$this->_sTableTrack}` WHERE `object_id` = ? AND `author_id` = ? LIMIT 1", $iObjectId, $iAuthorId);
-        if((int)$this->getOne($sQuery) == 0)
-        	return true;
-
-        $sQuery = $this->prepare("DELETE FROM `{$this->_sTableTrack}` WHERE `object_id` = ? AND `author_id` = ? LIMIT 1", $iObjectId, $iAuthorId);
+        $sQuery = $this->prepare("INSERT IGNORE INTO `{$this->_sTableTrack}` SET `object_id` = ?, `author_id` = ?, `date` = ?, `list_id` = ?", $iObjectId, $iAuthorId, time(), $iListId);
         return (int)$this->query($sQuery) > 0;
     }
+    
+    public function getList($aParams)
+    {
+        $aMethodParams = array();
+        switch($aParams['type']) {
+            case 'object_and_author':
+                $sMethod = 'getColumn';
+                $aMethodParams[0] = $this->prepare("SELECT `list_id` FROM `{$this->_sTableTrack}` WHERE `object_id` = ? AND `author_id` = ?", $aParams['object_id'], $aParams['author_id']);
+                break;
+                
+            case 'id':
+                $sMethod = 'getRow';
+                $aMethodParams[0] = $this->prepare("SELECT * FROM `{$this->_sTableLists}` WHERE `id` = ? ", $aParams['list_id']);
+                break;
+                
+            case 'info':
+                $sMethod = 'getRow';
+                $aMethodParams[0] = $this->prepare("SELECT MAX(`t`.`date`) `updated`, COUNT(`t`.`object_id`) `count`, `l`.`title`, `l`.`date` `created`, `l`.`allow_view_favorite_list_to` FROM `{$this->_sTableTrack}` `t` LEFT JOIN `{$this->_sTableLists}` `l` ON `t`.`list_id` = `l`.`id` WHERE `t`.`list_id` = ? AND `t`.`author_id` = ?", $aParams['list_id'], $aParams['author_id']);
+                break;
+            
+            case 'all':
+                $sMethod = 'getPairs';
+                $sQ = "SELECT `id`, `title` FROM `{$this->_sTableLists}` WHERE `author_id` = ? ORDER BY `date`";
+                if (isset($aParams['need_default']) && (bool)$aParams['need_default']){
+                    $sQ = "SELECT 0 `id`, '" . _t('_sys_txt_default_favorite_list') . "' `title` UNION (" . $sQ . ")";
+                }
+                
+                $aMethodParams[0] = $this->prepare($sQ, $aParams['author_id']);
+                $aMethodParams[1] = 'id';
+                $aMethodParams[2] = 'title';
+                break;
+                
+            case 'active':
+                $sMethod = 'getPairs';
+                $aMethodParams[0] = "SELECT `l`.`id`, `l`.`title` FROM `{$this->_sTableLists}` `l` INNER JOIN  `{$this->_sTableTrack}` `t` ON `t`.`list_id` = `l`.`id` WHERE `l`.`author_id` = :author GROUP BY `l`.`id`, `l`.`title` ORDER BY `l`.`date` DESC";
+                $aMethodParams[1] = 'id';
+                $aMethodParams[2] = 'title';
+                
+                $aBindings = array(
+                    'author' => $aParams['author_id'],
+                );
+                
+                if (isset($aParams['need_default']) && (bool)$aParams['need_default'])
+                    $aMethodParams[0] = "SELECT 0 `id`, '" . _t('_sys_txt_default_favorite_list') . "' `title` UNION (" . $aMethodParams[0] . ")";
+                
+                if (isset($aParams['limit'])){
+                    $aMethodParams[0] .= " LIMIT " . $aParams['start'] . ", " . $aParams['limit'];
+                }
+                
+                $aMethodParams[3] = $aBindings;
+                break;
+        }
+        return call_user_func_array(array($this, $sMethod), $aMethodParams);
+    }
+    
+    public function addList($iAuthorId, $sTitle, $sVisibility)
+    {
+        $sQuery = $this->prepare("INSERT INTO `{$this->_sTableLists}` SET `author_id` = ?, `title` = ?, `allow_view_favorite_list_to` = ?, `date` = ?", $iAuthorId, $sTitle, $sVisibility, time());
+        $this->query($sQuery);
+        return $this->lastId();
+    }
+    
+    public function editList($iListId, $sTitle, $sVisibility)
+    {
+        $sQuery = $this->prepare("UPDATE `{$this->_sTableLists}` SET `title` = ?, `allow_view_favorite_list_to` = ? WHERE `id` = ?", $sTitle, $sVisibility, $iListId);
+        $this->query($sQuery);
+        return $this->lastId();
+    }
+    
+    public function deleteList($iListId)
+    {
+        $sQuery = $this->prepare("DELETE FROM  `{$this->_sTableLists}` WHERE  `id` = ?", $iListId);
+        $this->query($sQuery);
+        
+        $sQuery = $this->prepare("DELETE FROM  `{$this->_sTableTrack}` WHERE  `list_id` = ?", $iListId);
+        $this->query($sQuery);
+    }
 }
 
 /** @} */

+ 5 - 0
inc/classes/BxDolPrivacy.php

@@ -288,6 +288,11 @@ class BxDolPrivacy extends BxDolFactory implements iBxDolFactoryObject
 
         return in_array(BX_DOL_PG_FRIENDS_SELECTED, $aGroups) || in_array(BX_DOL_PG_RELATIONS_SELECTED, $aGroups);                
     }
+        
+    public function getGroupsBy($aParams)
+    {
+        return $this->_oDb->getGroupsBy($aParams);          
+    }
 
     public function getGroupCustom($aParams)
     {

+ 64 - 6
inc/js/classes/BxDolFavorite.js

@@ -36,22 +36,77 @@ BxDolFavorite.prototype.toggleByPopup = function(oLink) {
 };
 
 BxDolFavorite.prototype.favorite = function(oLink) {
-	var $this = this;
+    var $this = this;
     var oData = this._getDefaultParams();
     oData['action'] = 'Favorite';
 
-    this._oParent = oLink;
+    this._oParent = $(oLink);
 
     $.get(
     	this._sActionsUrl,
     	oData,
     	function(oData) {
-    		$this.processJson(oData, oLink);
+    	    $this.processJson(oData, this._oParent);
     	},
     	'json'
     );
 };
 
+BxDolFavorite.prototype.showNewList = function () {
+    $("#bx-form-element-title").show();
+    $("#bx-form-element-allow_view_favorite_list_to").show();
+    $("#bx-form-element-new_list").hide();
+}
+
+BxDolFavorite.prototype.cmtDelete = function (obj, list_id) {
+    var $this = this;
+    var oData = this._getDefaultParams();
+    oData['action'] = 'DeleteList';
+    oData['list_id'] = list_id;
+
+    this._oParent = $(oLink);
+
+    $.get(
+    	this._sActionsUrl,
+    	oData,
+    	function (oData) {
+    	    $this.processJson(oData, this._oParent);
+    	},
+    	'json'
+    );
+}
+
+BxDolFavorite.prototype.cmtEdit = function (obj, list_id) {
+    var $this = this;
+    var oData = $this._getDefaultParams();
+    oData['action'] = 'EditList';
+    oData['list_id'] = list_id;
+
+    $.get(
+        $this._sActionsUrl,
+        oData,
+        function (oData) {
+            $this.processJson(oData, $(obj));
+        },
+        'json'
+    );
+}
+
+BxDolFavorite.prototype.onEditFavoriteList = function (oData, oElement) {
+    var $this = this;
+    var fContinue = function() {
+        if(oData && oData.code != 0)
+            return;
+        location.reload();
+    };
+
+    if (oData && oData.msg != undefined && oData.msg.length > 0)
+        bx_alert(oData.msg, fContinue);
+    else
+        fContinue();
+}
+
+
 BxDolFavorite.prototype.onFavorite = function(oData, oElement)
 {
 	var $this = this;
@@ -90,7 +145,7 @@ BxDolFavorite.prototype.processJson = function(oData, oElement) {
 	var fContinue = function() {
 		//--- Show Popup
 	    if(oData && oData.popup != undefined) {
-	    	$('#' + oData.popup_id).remove();
+	        $('#' + oData.popup_id).remove();
 
 	    	$(oData.popup).hide().prependTo('body').dolPopup({
 	    		pointer: {
@@ -111,8 +166,11 @@ BxDolFavorite.prototype.processJson = function(oData, oElement) {
     //--- Show Message
     if(oData && oData.message != undefined)
         bx_alert(oData.message, fContinue);
-    else
-    	fContinue();
+	else
+        if (oData && oData.redirect != undefined)
+            document.location = oData.redirect;
+        else
+    	    fContinue();
 };
 
 BxDolFavorite.prototype._getButtons = function(oElement) {

+ 4 - 2
inc/js/functions.js

@@ -112,12 +112,14 @@ function getHtmlData( elem, url, callback, method , confirmation)
     	fPerform();
 }
 
-function loadDynamicBlockAutoPaginate (e, iStart, iPerPage, sAdditionalUrlParams) {
+function loadDynamicBlockAutoPaginate (e, iStart, iPerPage, sAdditionalUrlParams, sStartParamName, sPerPageParamName) {
 
     sUrl = location.href;
+    sStartParamName = typeof sStartParamName !== 'undefined' ?  sStartParamName : 'start';
+    sPerPageParamName = typeof sPerPageParamName !== 'undefined' ?  sPerPageParamName : 'per_page';
 
     sUrl = sUrl.replace(/start=\d+/, '').replace(/per_page=\d+/, '').replace(/[&\?]+$/, '');
-    sUrl = bx_append_url_params(sUrl, 'start=' + parseInt(iStart) + '&per_page=' + parseInt(iPerPage));
+    sUrl = bx_append_url_params(sUrl, sStartParamName + '=' + parseInt(iStart) + '&' + sPerPageParamName + '=' + parseInt(iPerPage));
     if ('undefined' != typeof(sAdditionalUrlParams))
         sUrl = bx_append_url_params(sUrl, sAdditionalUrlParams);
 

+ 42 - 2
install/sql/system.sql

@@ -1752,6 +1752,7 @@ CREATE TABLE `sys_objects_favorite` (
   `id` int(11) NOT NULL auto_increment,
   `name` varchar(64) NOT NULL,
   `table_track` varchar(32) NOT NULL,
+  `table_lists` varchar(32) NOT NULL,
   `is_on` tinyint(4) NOT NULL default '1',
   `is_undo` tinyint(4) NOT NULL default '1',
   `is_public` tinyint(4) NOT NULL default '1',
@@ -3103,6 +3104,7 @@ INSERT INTO `sys_objects_form` (`object`, `module`, `title`, `action`, `form_att
 ('sys_comment', 'system', '_sys_form_comment', 'cmts.php', 'a:3:{s:2:"id";s:17:"cmt-%s-form-%s-%d";s:4:"name";s:17:"cmt-%s-form-%s-%d";s:5:"class";s:14:"cmt-post-reply";}', 'cmt_submit', '', 'cmt_id', '', '', '', 0, 1, 'BxTemplCmtsForm', ''),
 ('sys_review', 'system', '_sys_form_review', 'cmts.php', 'a:3:{s:2:"id";s:17:"cmt-%s-form-%s-%d";s:4:"name";s:17:"cmt-%s-form-%s-%d";s:5:"class";s:14:"cmt-post-reply";}', 'cmt_submit', '', 'cmt_id', '', '', '', 0, 1, 'BxTemplCmtsReviewsForm', ''),
 ('sys_report', 'system', '_sys_form_report', 'report.php', 'a:3:{s:2:"id";s:0:"";s:4:"name";s:0:"";s:5:"class";s:17:"bx-report-do-form";}', 'submit', '', 'id', '', '', '', 0, 1, '', ''),
+('sys_favorite', 'system', '_sys_form_favorite', 'favorite.php', 'a:3:{s:2:"id";s:0:"";s:4:"name";s:0:"";s:5:"class";s:19:"bx-favorite-do-form";}', 'submit', '', 'id', '', '', '', 0, 1, '', ''),
 ('sys_privacy_group_custom', 'system', '_sys_form_ps_group_custom', 'privacy.php', '', 'do_submit', 'sys_privacy_groups_custom', 'id', '', '', '', 0, 1, 'BxTemplPrivacyFormGroupCustom', ''),
 ('sys_labels', 'system', '_sys_form_labels', 'label.php', '', 'do_submit', '', '', '', '', '', 0, 1, 'BxTemplLabelForm', ''),
 ('sys_wiki', 'system', '_sys_form_wiki', '', '', 'do_submit', 'sys_pages_wiki_blocks', 'id', '', '', '', 0, 1, 'BxTemplFormWiki', '');
@@ -3138,6 +3140,8 @@ INSERT INTO `sys_form_displays` (`display_name`, `module`, `object`, `title`, `v
 ('sys_review_post', 'system', 'sys_review', '_sys_form_review_display_post', 0),
 ('sys_review_edit', 'system', 'sys_review', '_sys_form_review_display_edit', 0),
 ('sys_report_post', 'system', 'sys_report', '_sys_form_display_report_post', 0),
+('sys_favorite_add', 'system', 'sys_favorite', '_sys_form_display_favorite_add', 0),
+('sys_favorite_list_edit', 'system', 'sys_favorite', '_sys_form_display_favorite_list_edit', 0),
 ('sys_privacy_group_custom_manage', 'system', 'sys_privacy_group_custom', '_sys_form_display_ps_gc_manage', 0),
 ('sys_labels_select', 'system', 'sys_labels', '_sys_form_labels_display_select', 0),
 ('sys_wiki_edit', 'system', 'sys_wiki', '_sys_form_display_wiki_edit', 0),
@@ -3252,6 +3256,17 @@ INSERT INTO `sys_form_inputs` (`object`, `module`, `name`, `value`, `values`, `c
 ('sys_report', 'system', 'text', '', '', 0, 'textarea', '_sys_form_report_input_caption_system_text', '_sys_form_report_input_caption_text', '', 0, 0, 0, '', '', '', '', '', '', 'Xss', '', 1, 0),
 ('sys_report', 'system', 'submit', '_sys_form_report_input_caption_submit', '', 0, 'submit', '_sys_form_report_input_caption_system_submit', '', '', 0, 0, 0, '', '', '', '', '', '', '', '', 0, 0),
 
+('sys_favorite', 'system', 'sys', '', '', 0, 'hidden', '_sys_form_favorite_input_caption_system_sys', '', '', 0, 0, 0, '', '', '', '', '', '', '', '', 0, 0),
+('sys_favorite', 'system', 'list_id', '', '', 0, 'hidden', '_sys_form_favorite_input_caption_system_list_id', '', '', 0, 0, 0, '', '', '', '', '', '', '', '', 0, 0),
+('sys_favorite', 'system', 'object_id', '', '', 0, 'hidden', '_sys_form_favorite_input_caption_system_object_id', '', '', 0, 0, 0, '', '', '', '', '', '', 'Int', '', 0, 0),
+('sys_favorite', 'system', 'action', '', '', 0, 'hidden', '_sys_form_favorite_input_caption_system_action', '', '', 0, 0, 0, '', '', '', '', '', '', '', '', 0, 0),
+('sys_favorite', 'system', 'id', '', '', 0, 'hidden', '_sys_form_favorite_input_caption_system_id', '', '', 0, 0, 0, '', '', '', '', '', '', 'Int', '', 0, 0),
+('sys_favorite', 'system', 'list', '', '#!sys_report_types', 0, 'select', '_sys_form_favorite_input_caption_system_list', '_sys_form_favorite_input_caption_list', '', 1, 0, 0, '', '', '', 'Avail', '', '_Please select value', 'Xss', '', 1, 0),
+('sys_favorite', 'system', 'new_list', '_sys_form_favorite_input_caption_button_new_list', '', 0, 'button', '', '', '', 0, 0, 0, 'a:1:{s:7:"onclick";s:25:"{js_object}.showNewList()";}', '', '', '', '', '', 'Xss', '', 1, 0),
+('sys_favorite', 'system', 'title', '', '', 0, 'text', '_sys_form_favorite_input_caption_system_title', '_sys_form_favorite_input_caption_title', '', 0, 0, 0, '', '', '', '', '', '', '', '', 1, 0),
+('sys_favorite', 'system', 'allow_view_favorite_list_to', '', '', 0, 'custom', '_sys_form_favorite_input_caption_system_allow_view_to', '_sys_form_favorite_input_caption_allow_view_to', '', 0, 0, 0, '', '', '', '', '', '', 'Xss', '', 1, 0),
+('sys_favorite', 'system', 'submit', '_sys_form_favorite_input_caption_submit', '', 0, 'submit', '_sys_form_favorite_input_caption_system_submit', '', '', 0, 0, 0, '', '', '', '', '', '', '', '', 0, 0),
+
 ('sys_privacy_group_custom', 'system', 'profile_id', '', '', 0, 'hidden', '_sys_form_ps_gc_input_caption_system_profile_id', '', '', 0, 0, 0, '', '', '', '', '', '', 'Int', '', 0, 0),
 ('sys_privacy_group_custom', 'system', 'content_id', '', '', 0, 'hidden', '_sys_form_ps_gc_input_caption_system_content_id', '', '', 0, 0, 0, '', '', '', '', '', '', 'Int', '', 0, 0),
 ('sys_privacy_group_custom', 'system', 'object', '', '', 0, 'hidden', '_sys_form_ps_gc_input_caption_system_object', '', '', 0, 0, 0, '', '', '', '', '', '', 'Xss', '', 0, 0),
@@ -3416,6 +3431,24 @@ INSERT INTO `sys_form_display_inputs` (`display_name`, `input_name`, `visible_fo
 ('sys_report_post', 'text', 2147483647, 1, 6),
 ('sys_report_post', 'submit', 2147483647, 1, 7),
 
+('sys_favorite_add', 'sys', 2147483647, 1, 1),
+('sys_favorite_add', 'object_id', 2147483647, 1, 2),
+('sys_favorite_add', 'action', 2147483647, 1, 3),
+('sys_favorite_add', 'id', 2147483647, 0, 4),
+('sys_favorite_add', 'list', 2147483647, 1, 5),
+('sys_favorite_add', 'new_list', 2147483647, 1, 6),
+('sys_favorite_add', 'title', 2147483647, 1, 7),
+('sys_favorite_add', 'allow_view_favorite_list_to', 2147483647, 1, 8),
+('sys_favorite_add', 'submit', 2147483647, 1, 9),
+
+('sys_favorite_list_edit', 'sys', 2147483647, 1, 1),
+('sys_favorite_list_edit', 'list_id', 2147483647, 1, 2),
+('sys_favorite_list_edit', 'object_id', 2147483647, 1, 3),
+('sys_favorite_list_edit', 'action', 2147483647, 1, 4),
+('sys_favorite_list_edit', 'title', 2147483647, 1, 5),
+('sys_favorite_list_edit', 'allow_view_favorite_list_to', 2147483647, 1, 6),
+('sys_favorite_list_edit', 'submit', 2147483647, 1, 7),
+
 ('sys_privacy_group_custom_manage', 'profile_id', 2147483647, 1, 1),
 ('sys_privacy_group_custom_manage', 'content_id', 2147483647, 1, 2),
 ('sys_privacy_group_custom_manage', 'object', 2147483647, 1, 3),
@@ -3900,7 +3933,8 @@ INSERT INTO `sys_objects_menu` (`object`, `title`, `set_name`, `module`, `templa
 ('sys_create_post', '_sys_menu_title_create_post', 'sys_add_content_links', 'system', 15, 0, 1, 'BxTemplMenuCreatePost', ''),
 ('sys_add_relation', '_sys_menu_title_add_relation', '', 'system', 6, 0, 1, 'BxTemplMenuAddRelation', ''),
 ('sys_vote_reactions_do', '_sys_menu_title_vote_reactions_do', '', 'system', 3, 0, 1, 'BxTemplVoteReactionsMenuDo', ''),
-('sys_wiki', '_sys_menu_title_wiki', 'sys_wiki', 'system', 6, 0, 1, 'BxTemplMenuWiki', '');
+('sys_wiki', '_sys_menu_title_wiki', 'sys_wiki', 'system', 6, 0, 1, 'BxTemplMenuWiki', ''),
+('sys_favorite_list', '_sys_menu_title_favorite_list', 'sys_favorite_list', 'system', 9, 0, 1, '', '');
 
 CREATE TABLE IF NOT EXISTS `sys_menu_sets` (
   `set_name` varchar(64) NOT NULL,
@@ -3932,7 +3966,8 @@ INSERT INTO `sys_menu_sets` (`set_name`, `module`, `title`, `deletable`) VALUES
 ('sys_switch_language', 'system', '_sys_menu_set_title_switch_language', 0),
 ('sys_switch_template', 'system', '_sys_menu_set_title_switch_template', 0),
 ('sys_social_sharing', 'system', '_sys_menu_set_title_sys_social_sharing', 0),
-('sys_wiki', 'system', '_sys_menu_set_title_sys_wiki', 0);
+('sys_wiki', 'system', '_sys_menu_set_title_sys_wiki', 0),
+('sys_favorite_list', 'system', '_sys_menu_set_title_sys_favorite_list', 0);
 
 CREATE TABLE IF NOT EXISTS `sys_menu_items` (
   `id` int(11) NOT NULL AUTO_INCREMENT,
@@ -4065,6 +4100,11 @@ INSERT INTO `sys_menu_items`(`set_name`, `module`, `name`, `title_system`, `titl
 ('sys_wiki', 'system', 'translate', '', '_sys_menu_item_title_wiki_translate', '', '', '', 'language', '', '', 0, 2147483646, '', 1, 0, 1, 4),
 ('sys_wiki', 'system', 'history', '', '_sys_menu_item_title_wiki_history', '', '', '', 'history', '', '', 0, 2147483646, '', 1, 0, 1, 5);
 
+-- favorite list menu
+INSERT INTO `sys_menu_items`(`set_name`, `module`, `name`, `title_system`, `title`, `link`, `onclick`, `target`, `icon`, `addon`, `submenu_object`, `submenu_popup`, `visible_for_levels`, `visibility_custom`, `active`, `copyable`, `editable`, `order`) VALUES 
+('sys_favorite_list', 'system', 'edit', '', '_sys_menu_item_title_favorite_list_edit', 'javascript:void(0)', 'javascript:{js_object}.cmtEdit(this, {list_id})', '', 'edit', '', '', 0, 2147483646, '', 1, 0, 1, 1),
+('sys_favorite_list', 'system', 'delete', '', '_sys_menu_item_title_wiki_favorite_list_delete', 'javascript:void(0)', 'javascript:{js_object}.cmtDelete(this, {list_id})', '', 'times', '', '', 0, 2147483646, '', 1, 0, 1, 2);
+
 -- --------------------------------------------------------
 
 

+ 7 - 0
template/css/favorite.css

@@ -62,6 +62,13 @@ div.bx-favorite div.bx-favorite-counter-holder {
 	border-width: 0px;
 }
 
+.bx-favorite-do-form .bx-form-input-checkbox_set {
+    min-width:250px;
+}
+.bx-favorite-do-form .bx-form-input-checkbox_set label{
+    white-space: pre;
+}
+
 /*--- Counter Styles ---*/
 .bx-favorite-counter-holder .bx-favorite-counter {
     line-height: normal;

+ 25 - 0
template/favorite_do_favorite_popup.html

@@ -0,0 +1,25 @@
+<div class="__style_prefix__-do-form">
+    <div class="__style_prefix__-do-form-cnt bx-def-padding">
+        __form__
+        <script language="javascript">
+            $(document).ready(function () {
+                $("#__form_id__ #bx-form-element-title").hide();
+                $("#__form_id__ #bx-form-element-allow_view_favorite_list_to").hide();
+
+                $("#__form_id__").ajaxForm({ 
+                    dataType: "json",
+                    beforeSubmit: function (formData, jqForm, options) {
+                        bx_loading($("#__form_id__"), true);
+                    },
+                    success: function (oData) {
+                        bx_loading($("#__form_id__"), false);
+
+                        $(".bx-popup-applied:visible").dolPopupHide();
+
+                        __js_object__.processJson(oData);
+                    }
+                });
+            });
+        </script>
+    </div>
+</div>

+ 23 - 0
template/favorite_edit_favorite_list.html

@@ -0,0 +1,23 @@
+<div class="__style_prefix__-do-form">
+    <div class="__style_prefix__-do-form-cnt bx-def-padding">
+        __form__
+        <script language="javascript">
+            $(document).ready(function () {
+                
+                $("#__form_id__").ajaxForm({ 
+                    dataType: "json",
+                    beforeSubmit: function (formData, jqForm, options) {
+                        bx_loading($("#__form_id__"), true);
+                    },
+                    success: function (oData) {
+                        bx_loading($("#__form_id__"), false);
+
+                        $(".bx-popup-applied:visible").dolPopupHide();
+
+                        __js_object__.processJson(oData);
+                    }
+                });
+            });
+        </script>
+    </div>
+</div>

+ 130 - 1
template/scripts/BxBaseFavorite.php

@@ -37,7 +37,9 @@ class BxBaseFavorite extends BxDolFavorite
             'main' => 'bx-favorite-' . $sHtmlId,
             'counter' => 'bx-favorite-counter-' . $sHtmlId,
             'do_link' => 'bx-favorite-do-link-' . $sHtmlId,
-            'by_popup' => 'bx-favorite-by-popup-' . $sHtmlId
+            'by_popup' => 'bx-favorite-by-popup-' . $sHtmlId,
+            'do_popup' => 'bx-favorite-do-popup-' . $sHtmlId,
+            'do_form' => 'bx-favorite-do-form-' . $sHtmlId,
         );
 
         $this->_aElementDefaults = array(
@@ -205,6 +207,133 @@ class BxBaseFavorite extends BxDolFavorite
             )
         ));
     }
+    
+    protected function _getFavorite()
+    {
+        if (!$this->isEnabled())
+           return array('code' => 1, 'message' => _t('_favorite_err_not_enabled'));
+
+        $iAuthorId = $this->_getAuthorId();
+        $iObjectId = $this->getId();
+        $iObjectAuthorId = $this->_oQuery->getObjectAuthorId($iObjectId);
+        
+        $oForm = $this->_getFormObject($this->_sFormDisplayAdd);
+        $oForm->setId($this->_aHtmlIds['do_form']);
+        $oForm->setName($this->_aHtmlIds['do_form']);
+        $oForm->aParams['db']['table'] = $this->_aSystem['table_track'];
+        $oForm->aInputs['sys']['value'] = $this->_sSystem;
+        $oForm->aInputs['object_id']['value'] = $iObjectId;
+
+        $oForm->aInputs['action']['value'] = 'Favorite';
+        $oForm->aInputs['list']['values'] = $this->_oQuery->getList(array('type' => 'all', 'author_id' => $iAuthorId, 'need_default' => true));
+        $oForm->aInputs['list']['value'] = $this->_oQuery->getList(array('type' => 'object_and_author', 'object_id' => $iObjectId, 'author_id' => $iAuthorId));
+        
+        $oModule = BxDolModule::getInstance($this->_aSystem["name"]);
+        $CNF = $oModule->_oConfig->CNF;    
+       
+        $oPrivacy = BxDolPrivacy::getObjectInstance($CNF["OBJECT_PRIVACY_LIST_VIEW"]);
+        if(!$oPrivacy) 
+            return;
+        
+        $aSave = array('db' => array('pass' => 'Xss'));
+        $aGroupChooser = $oPrivacy->getGroupChooser($CNF["OBJECT_PRIVACY_LIST_VIEW"]);
+        $oForm->aInputs["allow_view_favorite_list_to"] = array_merge($oForm->aInputs["allow_view_favorite_list_to"], $aGroupChooser, $aSave);
+        
+        if($oForm->isSubmittedAndValid()) {
+           
+            $mList = $oForm->getCleanValue('list');
+            $aList = is_array($mList) ? $mList : array();
+            
+            $sTitle = $oForm->getCleanValue('title');
+            if ($sTitle){
+                 $sAllowViewTo = $oForm->getCleanValue('allow_view_favorite_list_to');
+                 $iAddList = $this->_oQuery->addList($iAuthorId, $sTitle, $sAllowViewTo);
+                 array_push($aList, $iAddList);
+            }
+            $this->_oQuery->clearFavorite($iObjectId, $iAuthorId);
+           
+            $bPerformed = count($aList) > 0 ? true: false;
+            
+            foreach($aList as $iList) {
+                $this->_oQuery->doFavorite($iObjectId, $iAuthorId, $iList);
+            }
+            bx_alert($this->_sSystem, 'favorite', $iObjectId, $iAuthorId, array('favorite_author_id' => $iAuthorId, 'object_author_id' => $iObjectAuthorId, 'list_ids' => $aList));
+            bx_alert('favorite', 'do', 0, $iAuthorId, array('object_system' => $this->_sSystem, 'object_id' => $iObjectId, 'object_author_id' => $iObjectAuthorId, 'list_ids' => $aList));
+            
+            $aFavorite = $this->_oQuery->getFavorite($iObjectId);
+            
+            return array(
+        	    'eval' => $this->getJsObjectName() . '.onFavorite(oData, oElement)',
+        	    'code' => 0, 
+        	    'count' => $aFavorite['count'],
+        	    'countf' => (int)$aFavorite['count'] > 0 ? $this->_getCounterLabel($aFavorite['count']) : '',
+                'label_icon' => $this->_getIconDoFavorite($bPerformed), 
+                'label_title' => _t($this->_getTitleDoFavorite($bPerformed)), 
+                'disabled' => false
+            );
+        }
+        
+        $sPopupId = $this->_aHtmlIds['do_popup'];
+        $sPopupContent = BxTemplFunctions::getInstance()->transBox($sPopupId, $this->_oTemplate->parseHtmlByName('favorite_do_favorite_popup.html', array(
+            'style_prefix' => $this->_sStylePrefix,
+                'js_object' => $this->getJsObjectName(),
+                'form' => str_replace('{js_object}', $this->getJsObjectName(), $oForm->getCode()),
+                'form_id' => $oForm->id,
+        )));
+
+        return array('popup' => $sPopupContent, 'popup_id' => $sPopupId);
+    }
+    
+    protected function _getEditList($aData)
+    {
+        if (!$this->isEnabled())
+            return array('code' => 1, 'message' => _t('_favorite_err_not_enabled'));
+        
+        $oForm = $this->_getFormObject($this->_sFormDisplayListEdit);
+        $oForm->setId($this->_aHtmlIds['do_form']);
+        $oForm->setName($this->_aHtmlIds['do_form']);
+        $oForm->aParams['db']['table'] = $this->_aSystem['table_track'];
+        $oForm->aInputs['sys']['value'] = $this->_sSystem;
+        $oForm->aInputs['list_id']['value'] = $aData['id'];
+        $oForm->aInputs['object_id']['value'] = 0;
+        $oForm->aInputs['action']['value'] = 'EditList';
+        $oModule = BxDolModule::getInstance($this->_aSystem["name"]);
+        $CNF = $oModule->_oConfig->CNF;    
+        
+        $oPrivacy = BxDolPrivacy::getObjectInstance($CNF["OBJECT_PRIVACY_LIST_VIEW"]);
+        if(!$oPrivacy) 
+            return;
+        
+        $aSave = array('db' => array('pass' => 'Xss'));
+        $aGroupChooser = $oPrivacy->getGroupChooser($CNF["OBJECT_PRIVACY_LIST_VIEW"]);
+        $oForm->aInputs["allow_view_favorite_list_to"] = array_merge($oForm->aInputs["allow_view_favorite_list_to"], $aGroupChooser, $aSave);
+        
+        $oForm->aInputs['title']['value'] = $aData['title'];
+        $oForm->aInputs['allow_view_favorite_list_to']['value'] = $aData['allow_view_favorite_list_to'];
+        //echo 'yyy';
+        if($oForm->isSubmittedAndValid()) {
+            
+            $sTitle = $oForm->getCleanValue('title');
+            if ($sTitle){
+                $sAllowViewTo = $oForm->getCleanValue('allow_view_favorite_list_to');
+                $this->_oQuery->editList($aData['id'], $sTitle, $sAllowViewTo);
+            }
+            return array(
+        	    'eval' => $this->getJsObjectName() . '.onEditFavoriteList(oData, oElement)',
+        	    'code' => 0, 
+            );
+        }
+         
+        $sPopupId = $this->_aHtmlIds['do_popup'];
+        $sPopupContent = BxTemplFunctions::getInstance()->transBox($sPopupId, $this->_oTemplate->parseHtmlByName('favorite_edit_favorite_list.html', array(
+            'style_prefix' => $this->_sStylePrefix,
+                'js_object' => $this->getJsObjectName(),
+                'form' => str_replace('{js_object}', $this->getJsObjectName(), $oForm->getCode()),
+                'form_id' => $oForm->id,
+        )));
+
+        return array('popup' => $sPopupContent, 'popup_id' => $sPopupId);
+    }
 
 	protected function _getFavoritedBy()
     {