RomanL 4 лет назад
Родитель
Сommit
76c4da1564
27 измененных файлов с 811 добавлено и 48 удалено
  1. 11 0
      inc/classes/BxDolBadgesQuery.php
  2. 34 0
      modules/base/text/template/css/main.css
  3. 7 0
      modules/boonex/forum/classes/BxForumCmts.php
  4. 6 0
      modules/boonex/forum/classes/BxForumConfig.php
  5. 2 0
      modules/boonex/forum/classes/BxForumDb.php
  6. 202 1
      modules/boonex/forum/classes/BxForumGrid.php
  7. 223 0
      modules/boonex/forum/classes/BxForumGridCategories.php
  8. 10 0
      modules/boonex/forum/classes/BxForumMenuViewActions.php
  9. 78 4
      modules/boonex/forum/classes/BxForumModule.php
  10. 15 4
      modules/boonex/forum/classes/BxForumTemplate.php
  11. 36 0
      modules/boonex/forum/install/langs/en.xml
  12. 37 20
      modules/boonex/forum/install/sql/enable.sql
  13. 9 3
      modules/boonex/forum/install/sql/install.sql
  14. 40 0
      modules/boonex/forum/js/main.js
  15. 7 0
      modules/boonex/forum/template/category_list.html
  16. 4 0
      modules/boonex/forum/template/css/grid_tools.css
  17. 42 0
      modules/boonex/forum/template/css/main.css
  18. 4 4
      modules/boonex/forum/template/entry-preview.html
  19. 3 0
      modules/boonex/forum/template/images/completed.svg
  20. 3 0
      modules/boonex/forum/template/images/idea.svg
  21. 3 0
      modules/boonex/forum/template/images/uncompleted.svg
  22. 4 0
      modules/boonex/forum/template/status.html
  23. 1 0
      modules/boonex/forum/template/thumb.html
  24. 13 1
      studio/template/css/general.css
  25. 4 4
      template/paginate_block.html
  26. 9 3
      template/scripts/BxBaseCmts.php
  27. 4 4
      template/scripts/BxBaseSearchResult.php

+ 11 - 0
inc/classes/BxDolBadgesQuery.php

@@ -90,6 +90,17 @@ class BxDolBadgesQuery extends BxDolDb
                 );
                 break;
                 
+            case 'by_module&badge':
+                $aMethod['name'] = 'getColumn';
+                $sSelectClause = "`soc`.`object_id`";
+                $sJoinClause = "INNER JOIN `sys_badges2objects` `soc` ON `sc`.`id` =  `soc`.`badge_id` ";
+                $sWhereClause = " AND `sc`.`module` = :module  AND `sc`.`id` = :badge_id";
+                $aMethod['params'][1] = array(
+                    'badge_id' => $aParams['badge_id'],
+                    'module' => $aParams['module']
+                );
+                break;
+                
             case 'id':
             	$aMethod['name'] = 'getRow';
             	$aMethod['params'][1] = array(

+ 34 - 0
modules/base/text/template/css/main.css

@@ -259,3 +259,37 @@
     overflow: hidden;
     align-items: center;
 }
+
+/* MEDIA: desktop */
+
+.bx-media-desktop .bx-layout-column-wide .bx-base-pofile-units-wrapper .bx-base-pofile-unit-with-cover {
+    -webkit-flex: 0 0 49.8%;
+    -ms-flex: 0 0 49.8%;
+    flex: 0 0 49.8%;
+}
+.bx-media-desktop #sys_search_results .bx-base-pofile-units-wrapper .bx-base-pofile-unit-with-cover,
+.bx-media-desktop .bx-layout-column-fullwidth .bx-base-pofile-units-wrapper .bx-base-pofile-unit-with-cover {
+    -webkit-flex: 0 0 33.25%;
+    -ms-flex: 0 0 33.25%;
+    flex: 0 0 33.25%;
+}
+
+.bx-media-desktop .bx-base-unit-showcase-wrapper .bx-base-pofile-unit-showcase {
+    width:calc(33.3%);
+}
+.bx-media-desktop .bx-layout-column-thin .bx-base-unit-showcase-wrapper .bx-base-pofile-unit-showcase {
+    width:calc(100%);
+}
+.bx-media-desktop .bx-layout-column-half .bx-base-unit-showcase-wrapper .bx-base-pofile-unit-showcase {
+    width:calc(50%);
+}
+
+.bx-media-desktop .bx-base-unit-showcase-wrapper .bx-base-pofile-unit-wo-info-showcase {
+    width:calc(6.25%);
+}
+.bx-media-desktop .bx-layout-column-thin .bx-base-unit-showcase-wrapper .bx-base-pofile-unit-wo-info-showcase {
+    width:calc(25.0%);
+}
+.bx-media-desktop .bx-layout-column-half .bx-base-unit-showcase-wrapper .bx-base-pofile-unit-wo-info-showcase {
+    width:calc(10.0%);
+}

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

@@ -79,6 +79,13 @@ class BxForumCmts extends BxTemplCmts
             $mixedBlock['title'] = _t('_bx_forum_page_block_title_entry_comments', $this->getCommentsCount());
         return $mixedBlock;
     }
+    
+    protected function _getCounterItems($iCmtsLimit, $iCmtsStart = 0)
+    {
+        $aContentInfo = $this->_oModule->_oDb->getContentInfoById($this->_iId);
+        $a = $this->_oQuery->getCommentsBy(array('type' => 'object_id', 'object_id' => $this->getId(), 'order_way' => 'desc', 'start' => $iCmtsStart, 'per_page' => $iCmtsLimit * 4));
+        return array_merge($a, [['cmt_author_id' => $aContentInfo['author']]]);
+    }
 
     protected function _getFormObject($sAction = BX_CMT_ACTION_POST)
     {

+ 6 - 0
modules/boonex/forum/classes/BxForumConfig.php

@@ -20,6 +20,8 @@ class BxForumConfig extends BxBaseModTextConfig
             'unsubscribe-discussion' => 'checkAllowedUnsubscribe',
             'stick-discussion' => 'checkAllowedStickAnyEntry',
             'unstick-discussion' => 'checkAllowedUnstickAnyEntry',
+            'resolve-discussion' => 'checkAllowedResolveAnyEntry',
+            'unresolve-discussion' => 'checkAllowedUnresolveAnyEntry',
             'lock-discussion' => 'checkAllowedLockAnyEntry',
             'unlock-discussion' => 'checkAllowedUnlockAnyEntry',
             'hide-discussion' => 'checkAllowedHideAnyEntry',
@@ -65,6 +67,8 @@ class BxForumConfig extends BxBaseModTextConfig
             'FIELD_COMMENTS' => 'comments',
             'FIELD_STICK' => 'stick',
             'FIELD_LOCK' => 'lock',
+            'FIELD_RESOLVE' => 'resolved',
+            'FIELD_RESOLVABLE' => 'resolvable',
             'FIELD_STATUS' => 'status',
             'FIELD_STATUS_ADMIN' => 'status_admin',
             'FIELD_LABELS' => 'labels',
@@ -111,6 +115,7 @@ class BxForumConfig extends BxBaseModTextConfig
             'OBJECT_GRID_FAVORITE' => 'bx_forum_favorite',
             'OBJECT_GRID_FEATURE' => 'bx_forum_feature',
             'OBJECT_GRID_ADMINISTRATION' => 'bx_forum_administration',
+            'OBJECT_GRID' => 'bx_forum',
             'OBJECT_GRID_COMMON' => 'bx_forum_common',
             'OBJECT_GRID_CATEGORIES' => 'bx_forum_categories',
             'OBJECT_STORAGE' => 'bx_forum_covers',
@@ -242,6 +247,7 @@ class BxForumConfig extends BxBaseModTextConfig
         $this->_aGridObjects = array(
             'common' => $this->CNF['OBJECT_GRID_COMMON'],
             'administration' => $this->CNF['OBJECT_GRID_ADMINISTRATION'],
+            'main' => $this->CNF['OBJECT_GRID'],
         );
     }
 }

+ 2 - 0
modules/boonex/forum/classes/BxForumDb.php

@@ -105,6 +105,8 @@ class BxForumDb extends BxBaseModTextDb
 			'unstick' => array($CNF['FIELD_STICK'] => 0),
 			'lock' =>  array($CNF['FIELD_LOCK'] => 1),
 			'unlock' =>  array($CNF['FIELD_LOCK'] => 0),
+            'resolve' =>  array($CNF['FIELD_RESOLVE'] => 1),
+			'unresolve' =>  array($CNF['FIELD_RESOLVE'] => 0),
 			'hide' =>  array($CNF['FIELD_STATUS_ADMIN'] => 'hidden'),
 			'unhide' =>  array($CNF['FIELD_STATUS_ADMIN'] => 'active')
 		);

+ 202 - 1
modules/boonex/forum/classes/BxForumGrid.php

@@ -11,16 +11,85 @@
 
 require_once(BX_DIRECTORY_PATH_INC . "design.inc.php");
 
+define('BX_FORUM_FILTER_STATUS_RESOLVED', 1);
+define('BX_FORUM_FILTER_STATUS_UNRESOLVED', 0);
+
+define('BX_FORUM_FILTER_ORDER_RECENT', 'latest');
+define('BX_FORUM_FILTER_ORDER_NEW', 'new');
+define('BX_FORUM_FILTER_ORDER_TOP', 'top');
+define('BX_FORUM_FILTER_ORDER_UPDATED', 'updated');
+define('BX_FORUM_FILTER_ORDER_POPULAR', 'popular');
+
 class BxForumGrid extends BxTemplGrid
 {
     protected $_oModule;
     protected $_sDefaultSource; 
+    
+    protected $_sFilter1Name;
+    protected $_sFilter1Value;
+    protected $_aFilter1Values;
+    
+    protected $_sFilter2Name;
+    protected $_sFilter2Value;
+    protected $_aFilter2Values;
+    
+    protected $_sFilter3Name;
+    protected $_sFilter3Value;
+    protected $_aFilter3Values;
+    
+    protected $_sParamsDivider;
 
     public function __construct ($aOptions, $oTemplate = false)
     {
         $this->_oModule = BxDolModule::getInstance('bx_forum');
 
         parent::__construct ($aOptions, $oTemplate);
+        
+        $this->_sFilter1Name = 'filter1';
+        $this->_aFilter1Values = array(
+            '' => _t('_bx_forum_grid_filter_resolved_all'),
+            BX_FORUM_FILTER_STATUS_RESOLVED => _t('_bx_forum_grid_filter_resolved_resolved'),
+            BX_FORUM_FILTER_STATUS_UNRESOLVED => _t('_bx_forum_grid_filter_resolved_unresolved'),
+        );
+        
+        $sFilter1 = bx_get($this->_sFilter1Name);
+        if(!empty($sFilter1)) {
+            $this->_sFilter1Value = bx_process_input($sFilter1);
+            $this->_aQueryAppend['filter1'] = $this->_sFilter1Value;
+        }
+        
+        $this->_sFilter2Name = 'filter2';
+        $aBadges = BxDolBadges::getInstance()->getData(['type' => 'by_module', 'module' => $this->_oModule->_aModule['name']]);
+        $this->_aFilter2Values = array(
+            '' => _t('_bx_forum_grid_filter_badges_all'),
+        );
+        
+        foreach($aBadges as $aBadge) {
+            $this->_aFilter2Values[$aBadge['id']] = $aBadge['text'];
+        }
+        
+        $sFilter2 = bx_get($this->_sFilter1Name);
+        if(!empty($sFilter2)) {
+            $this->_sFilter2Value = bx_process_input($sFilter2);
+            $this->_aQueryAppend['filter2'] = $this->_sFilter2Value;
+        }
+        
+        $this->_sFilter3Name = 'filter3';
+        $this->_aFilter3Values = array(
+            BX_FORUM_FILTER_ORDER_RECENT => _t('_bx_forum_grid_filter_order_recent'),
+            BX_FORUM_FILTER_ORDER_NEW => _t('_bx_forum_grid_filter_order_new'),
+            BX_FORUM_FILTER_ORDER_TOP => _t('_bx_forum_grid_filter_order_top'),
+            BX_FORUM_FILTER_ORDER_UPDATED => _t('_bx_forum_grid_filter_order_updated'),
+            BX_FORUM_FILTER_ORDER_POPULAR => _t('_bx_forum_grid_filter_order_popular'),
+        );
+        
+        $sFilter3 = bx_get($this->_sFilter3Name);
+        if(!empty($sFilter3)) {
+            $this->_sFilter1Value = bx_process_input($sFilter3);
+            $this->_aQueryAppend['filter3'] = $this->_sFilter1Value;
+        }
+        
+        $this->_sParamsDivider = '#-#';
 
         $this->_sDefaultSortingOrder = 'DESC';
         $this->_sDefaultSource = $this->_aOptions['source'];
@@ -38,6 +107,9 @@ class BxForumGrid extends BxTemplGrid
 
             unset($aParams['ajax_paginate']);
         }
+        
+        if ($aParams['type'])
+            $this->_sFilter3Value = $aParams['type'];
 
         parent::setBrowseParams($aParams);
 
@@ -118,10 +190,64 @@ class BxForumGrid extends BxTemplGrid
 
         return self::_getCellDefault($mixedValue, $sKey, $aField, $aRow);
     }
+    
+    protected function _getCellCategory($mixedValue, $sKey, $aField, $aRow)
+    {
+        $sIcon = '';
+        $o = BxDolCategory::getObjectInstance('bx_forum_cats');
+        
+        $aCategoryData = $this->_oModule->_oDb->getCategories(array('type' => 'by_category', 'category' => $aRow['cat']));
+
+        if(isset($aCategoryData['icon']))
+            $sIcon = $this->_oTemplate->getImage($aCategoryData['icon'], array('class' => 'sys-icon'));
+        $mixedValue = $this->_oModule->_oTemplate->parseHtmlByName('thumb.html', ['icon' => $sIcon, 'title' => $o->getCategoryTitle($aRow['cat'])]);
+        return self::_getCellDefault($mixedValue, $sKey, $aField, $aRow);
+    }
+    
+    protected function _getCellRating($mixedValue, $sKey, $aField, $aRow)
+    {
+        $CNF = &$this->_oModule->_oConfig->CNF;
+
+        $oObject = isset($CNF['OBJECT_SCORES']) ? BxDolScore::getObjectInstance($CNF['OBJECT_SCORES'], $aRow[$CNF['FIELD_ID']]) : null;
+        $mixedValue = $oObject ? $oObject->getElementInline() : '';
+        
+        return self::_getCellDefault($mixedValue, $sKey, $aField, $aRow);
+    }
+    
+    protected function _getCellParticipants($mixedValue, $sKey, $aField, $aRow)
+    {
+        $CNF = &$this->_oModule->_oConfig->CNF;
+    	$oObject = isset($CNF['OBJECT_COMMENTS']) ? BxDolCmts::getObjectInstance($CNF['OBJECT_COMMENTS'], $aRow[$CNF['FIELD_ID']]) : null;
+      
+        $mixedValue = $oObject ? $oObject->getCounter(['show_counter_empty' => true, 'show_counter' => false, 'show_counter_style' => 'simple', 'dynamic_mode' => true, 'caption' => '', 'show_icon' => false, 'caption_empty' => '']) : '';
+
+        return self::_getCellDefault($mixedValue, $sKey, $aField, $aRow);
+    }
+    
+     protected function _getCellStatus($mixedValue, $sKey, $aField, $aRow)
+    {
+    	$CNF = &$this->_oModule->_oConfig->CNF;
+
+        $oObject = isset($CNF['OBJECT_COMMENTS']) ? BxDolCmts::getObjectInstance($CNF['OBJECT_COMMENTS'], $aRow[$CNF['FIELD_ID']]) : null;
+        $sIcon = '';
+        if ($aRow['resolvable']){
+            if ($aRow['resolved']){
+                $sIcon .= 'completed';
+            }
+            else{
+                $sIcon .= 'uncompleted';
+            }   
+        }
+        else{
+            $sIcon .= 'idea'; 
+        }
+        $mixedValue = $this->_oModule->_oTemplate->parseHtmlByName('status.html', ['icon' => BX_DOL_URL_MODULES . $this->_oModule->_aModule['path'] .'template/images/'. $sIcon . '.svg', 'counter' => (int)$oObject->getCommentsCountAll()]); 
+        return self::_getCellDefault($mixedValue, $sKey, $aField, $aRow);
+    }
 
     protected function _getCellText($mixedValue, $sKey, $aField, $aRow)
     {
-        $mixedValue = $this->_oModule->_oTemplate->getEntryPreview($aRow);
+        $mixedValue = $this->_oModule->_oTemplate->getEntryPreview($aRow, ['show_meta_counters' => false, 'show_meta_reply' => false]);
 
         return self::_getCellDefault($mixedValue, $sKey, $aField, $aRow);
     }
@@ -136,6 +262,8 @@ class BxForumGrid extends BxTemplGrid
 
     protected function _getDataSql($sFilter, $sOrderField, $sOrderDir, $iStart, $iPerPage)
     {
+        $CNF = $this->_oModule->_oConfig->CNF;
+        
     	$sSelectClause = $sJoinClause = $sWhereClause = $sGroupByClause = '';
 
     	//--- Check status
@@ -182,7 +310,23 @@ class BxForumGrid extends BxTemplGrid
             if(!empty($sGroupByClauseBrowse))
                 $sGroupByClause .= " GROUP BY " . $sGroupByClauseBrowse;
         }
+        
+        if(strpos($sFilter, $this->_sParamsDivider) !== false)
+            list($this->_sFilter1Value, $this->_sFilter2Value, $this->_sFilter3Value, $sFilter) = explode($this->_sParamsDivider, $sFilter);
+        
+        $sFilterSql = "";
 
+        // filter by resolved status
+        if(isset($this->_sFilter1Value) && $this->_sFilter1Value != ''){
+            $sWhereClause .= " AND `" . $CNF['TABLE_ENTRIES'] . "`.`" . $CNF['FIELD_RESOLVABLE'] . "` = 1 AND `" . $CNF['TABLE_ENTRIES'] . "`.`" . $CNF['FIELD_RESOLVE'] . "` = " . $this->_sFilter1Value;
+        }
+        
+        // filter by badges
+        if(isset($this->_sFilter2Value) && $this->_sFilter2Value != ''){
+            $aObjects = BxDolBadges::getInstance()->getData(['type' => 'by_module&badge', 'badge_id' => $this->_sFilter2Value, 'module' => $this->_oModule->_aModule['name']]);
+            $sWhereClause .= " AND `" . $CNF['TABLE_ENTRIES'] . "`.`" . $CNF['FIELD_ID'] . "` IN (" . implode(',', $aObjects ) . ")";
+        }
+        
         $this->_aOptions['source'] = sprintf($this->_sDefaultSource, $sSelectClause, $sJoinClause, $sWhereClause, $sGroupByClause);
         return parent::_getDataSql($sFilter, $sOrderField, $sOrderDir, $iStart, $iPerPage);
     }
@@ -191,7 +335,15 @@ class BxForumGrid extends BxTemplGrid
     {
         $CNF = &$this->_oModule->_oConfig->CNF;
 
+        if(isset($this->_sFilter3Value) && $this->_sFilter3Value != ''){
+            $sOrderField = $this->_aBrowseParams['type'] = $this->_sFilter3Value;
+            if (!empty($this->_aBrowseParams['type']) && $this->_aBrowseParams['type'] != 'partaken'){
+                $this->_aBrowseParams['type'] = $this->_aBrowseParams['type'] = $this->_sFilter3Value;
+            }
+        }
+        
     	$sOrder = parent::_getDataSqlOrderClause($sOrderByFilter, $sOrderField, $sOrderDir, true);
+                
         if(!empty($this->_aBrowseParams['type']))
             switch($this->_aBrowseParams['type']) {
                 case 'top':
@@ -414,6 +566,55 @@ class BxForumGrid extends BxTemplGrid
 
         return '';
     }
+    
+    protected function _getFilterControls ()
+    {
+        parent::_getFilterControls();
+        return  $this->_getFilterSelectOne($this->_sFilter3Name, $this->_sFilter3Value, $this->_aFilter3Values) . $this->_getFilterSelectOne($this->_sFilter1Name, $this->_sFilter1Value, $this->_aFilter1Values) . $this->_getFilterSelectOne($this->_sFilter2Name, $this->_sFilter2Value, $this->_aFilter2Values) . $this->_getSearchInput();
+    }
+    
+    protected function _getSearchInput()
+    {
+        $sJsObject = $this->_oModule->_oConfig->getJsObject('main');
+        $aInputSearch = array(
+            'type' => 'text',
+            'name' => 'search',
+            'attrs' => array(
+                'id' => 'bx-grid-search-' . $this->_sObject,
+                'onKeyup' => 'javascript:$(this).off(\'keyup focusout\'); ' . $sJsObject . '.onChangeFilter(this)',
+                'onBlur' => 'javascript:' . $sJsObject . '.onChangeFilter(this)',
+            )
+        );
+
+        $oForm = new BxTemplFormView(array());
+        return $oForm->genRow($aInputSearch);
+    }
+    
+    protected function _getFilterSelectOne($sFilterName, $sFilterValue, $aFilterValues)
+    {
+        if(empty($sFilterName) || empty($aFilterValues))
+            return '';
+
+        $CNF = &$this->_oModule->_oConfig->CNF;
+        $sJsObject = $this->_oModule->_oConfig->getJsObject('main');
+
+        foreach($aFilterValues as $sKey => $sValue)
+            $aFilterValues[$sKey] = _t($sValue);
+
+        $aInputModules = array(
+            'type' => 'select',
+            'name' => $sFilterName,
+            'attrs' => array(
+                'id' => 'bx-grid-' . $sFilterName . '-' . $this->_sObject,
+                'onChange' => 'javascript:' . $sJsObject . '.onChangeFilter(this)'
+            ),
+            'value' => $sFilterValue,
+            'values' => $aFilterValues
+        );
+
+        $oForm = new BxTemplFormView(array());
+        return $oForm->genRow($aInputModules);
+    }
 }
 
 /** @} */

+ 223 - 0
modules/boonex/forum/classes/BxForumGridCategories.php

@@ -23,12 +23,104 @@ class BxForumGridCategories extends BxTemplStudioGrid
         $this->_oModule = BxDolModule::getInstance('bx_forum');
         $this->_iVisibleForDefault = 2147483647;
     }
+    
+    protected function _getCellIcon ($mixedValue, $sKey, $aField, $aRow)
+    {
+        $mixedValue = '';
+        
+        $aData = $this->_oModule->_oDb->getCategories(array('type' => 'by_category', 'category' => $aRow['category']));
+        if (isset($aData['icon']))
+            $mixedValue = $aData['icon'];
+        
+        $mixedValue = $this->_oTemplate->getIcon($mixedValue, array('class' => 'bx-item-icon bx-def-border'));
+        return parent::_getCellDefault($mixedValue, $sKey, $aField, $aRow);
+    }
 
     public function getCode($isDisplayHeader = true)
     {
     	return $this->_oModule->_oTemplate->getJsCode('studio') . parent::getCode($isDisplayHeader);
     }
 
+    public function performActionEdit()
+    {
+        $sAction = 'edit';
+        
+        $aIds = bx_get('ids');
+        if (bx_get('category'))
+            $aIds = [bx_get('category')];
+        
+        if(!$aIds || !is_array($aIds)) {
+            $iId = (int)bx_get('id');
+            if(!$iId)
+                return echoJson(array());
+
+            $aIds = array($iId);
+        }
+
+        $iId = (int)array_shift($aIds);
+
+        $aData = $this->_oModule->_oDb->getCategories(array('type' => 'by_category', 'category' => $iId));
+        $bNeedInsert = false;
+        if (!isset($aData['category'])){
+            $aData = ['category' => $iId, 'icon' => '']; 
+            $bNeedInsert = true;
+        }
+            
+        $oForm = $this->_getForm('edit', $aData);
+        $oForm->initChecker();
+        if($oForm->isSubmittedAndValid()) {
+            $bIconImageCur = is_numeric($aData['icon']) && (int)$aData['icon'] != 0;
+            $bIconImageNew = !empty($_FILES['icon_image']['tmp_name']);
+
+            $sIconFont = $oForm->getCleanValue('icon');
+            $bIconFont = !empty($sIconFont);
+
+            if($bIconImageCur && ($bIconImageNew || $bIconFont)) {
+                $oStorage = BxDolStorage::getObjectInstance(BX_DOL_STORAGE_OBJ_IMAGES);
+                if(!$oStorage->deleteFile((int)$aData['icon'], 0)) {
+                    echoJson(array('msg' => _t('_bx_forum_grid_err_items_icon_image_remove')));
+                    return;
+                }
+            }
+
+            $sIcon = $sIconFont;
+            if($bIconImageNew) {
+                $oStorage = BxDolStorage::getObjectInstance(BX_DOL_STORAGE_OBJ_IMAGES);
+                $sIcon = $oStorage->storeFileFromForm($_FILES['icon_image'], false, 0);
+                if($sIcon === false) {
+                    echoJson(array('msg' => _t('_bx_forum_grid_err_items_icon_image') . $oStorage->getErrorString()));
+                    return;
+                }
+
+                $oStorage->afterUploadCleanup($sIcon, 0);
+            } else if($bIconImageCur && !$bIconFont)
+                $sIcon = $aData['icon'];
+            
+            BxDolForm::setSubmittedValue('icon', $sIcon, $oForm->aFormAttrs['method']);
+            if ($bNeedInsert){
+                $mixedResult = $oForm->insert();
+            }
+            else{
+                $mixedResult = $oForm->update($iId);
+            }
+            if(is_numeric($mixedResult))
+                $aRes = array('grid' => $this->getCode(false), 'blink' => $mixedResult);
+            else
+                $aRes = array('msg' => $mixedResult);
+            echoJson($aRes);
+        }
+        else {
+            $sContent = BxTemplStudioFunctions::getInstance()->popupBox('bx-forum-form-for-popup', _t('_bx_forum_grid_edit_popup'), $this->_oTemplate->parseHtmlByName('form_add_value.html', array(
+               'form_id' => $oForm->aFormAttrs['id'],
+               'form' => $oForm->getCode(true),
+               'object' => $this->_sObject,
+               'action' => $sAction
+           )));
+
+            echoJson(array('popup' => array('html' => $sContent, 'options' => array('closeOnOuterClick' => false))));
+        }
+    }
+    
 	public function performActionShowTo()
     {
         $sAction = 'show_to';
@@ -207,6 +299,137 @@ class BxForumGridCategories extends BxTemplStudioGrid
 
         return parent::_getDataArray($sFilter, $sOrderField, $sOrderDir, $iStart, $iPerPage);
     }
+    
+    protected function _getForm($sAction, $aData = array())
+    {
+        $aForm = array(
+            'form_attrs' => array(
+                'id' => 'adm-form-category-form-edit',
+                'action' => BX_DOL_URL_ROOT . 'grid.php?o=' . $this->_sObject . '&a=' . $sAction,
+                'method' => 'post'
+            ),
+            'params' => array (
+                'db' => array(
+                    'table' => 'bx_forum_categories',
+                    'key' => 'category',
+                    'uri' => '',
+                    'uri_title' => '',
+                    'submit_name' => 'do_submit'
+                ),
+                'checker_helper' => 'BxDolFormCheckerHelper'
+            ),
+            'inputs' => array (
+                'id' => array(
+                    'type' => 'hidden',
+                    'name' => 'category',
+                    'value' => isset($aData['category']) ? (int)$aData['category'] : 0,
+                    'db' => array (
+                        'pass' => 'Int',
+                    ),
+                ),
+                'icon' => array(
+                    'type' => 'textarea',
+                    'name' => 'icon',
+                    'caption' => _t('_bx_forum_grid_form_txt_badges_icon'),
+                    'info' => _t('_bx_forum_grid_form_dsc_badges_icon'),
+                    'value' => '',
+                    'required' => '0',
+                    'db' => array (
+                        'pass' => 'Xss',
+                    )
+                ),
+                'icon_image' => array(
+                    'type' => 'file',
+                    'name' => 'icon_image',
+                    'caption' => _t('_bx_forum_grid_form_txt_badges_icon_image'),
+                    'info' => _t('_bx_forum_grid_form_dsc_badges_icon_image'),
+                    'value' => '',
+                    'checker' => array (
+                        'func' => '',
+                        'params' => '',
+                        'error' => _t('_bx_forum_grid_form_err_badges_icon_image'),
+                    ),
+                ),
+                'icon_preview' => array(
+                    'type' => 'custom',
+                    'name' => 'icon_preview',
+                    'caption' => _t('_bx_forum_grid_form_txt_badges_icon_image_old'),
+                    'content' => ''
+                ),
+                'controls' => array(
+                    'name' => 'controls',
+                    'type' => 'input_set',
+                    array(
+                        'type' => 'submit',
+                        'name' => 'do_submit',
+                        'value' => _t('_bx_forum_grid_form_btn_badges_submit'),
+                    ),
+                    array (
+                        'type' => 'reset',
+                        'name' => 'close',
+                        'value' => _t('_bx_forum_grid_form_btn_badges_cancel'),
+                        'attrs' => array(
+                            'onclick' => "$('.bx-popup-applied:visible').dolPopupHide()",
+                            'class' => 'bx-def-margin-sec-left',
+                        ),
+                    )
+                )
+            )
+        );
+        
+        switch($sAction) {
+            case 'edit':
+                $sIconImage = $sIconFont = "";
+                if(!empty($aData['icon'])) {
+                    if(is_numeric($aData['icon']) && (int)$aData['icon'] != 0) {
+                        $oStorage = BxDolStorage::getObjectInstance(BX_DOL_STORAGE_OBJ_IMAGES);
+
+                        $sIconImage = $oStorage->getFileUrlById((int)$aData['icon']);
+                    }
+                    else {
+                        $sIconFont = $aData['icon'];
+                        $aForm['inputs']['icon']['value'] = htmlspecialchars($sIconFont);
+                    }
+                }
+
+                $aForm['inputs']['icon_preview']['content'] = $this->_getIconPreview($aData['category'], $sIconImage, $sIconFont);
+                break;
+        }
+        
+        return new BxTemplStudioFormView($aForm);
+    }
+    
+    protected function _getIconPreview($iId, $sIconImage = '', $sIcon = '')
+    {
+        $bIconImage = !empty($sIconImage);
+		
+        $aIcons = BxTemplFunctions::getInstanceWithTemplate($this->_oTemplate)->getIcon($sIcon);
+        $sIconHtml = $aIcons[2] . $aIcons[3] . $aIcons[4];
+		$bIconHtml = !empty($sIconHtml) && !$bIconImage;
+        
+        return $this->_oTemplate->parseHtmlByName('item_icon_preview.html', array(
+            'id' => $iId,
+            'bx_if:show_icon_empty' => array(
+                'condition' => !$bIconImage && !$bIconHtml,
+                'content' => array()
+            ),
+            'bx_if:show_icon_image' => array(
+                'condition' => $bIconImage,
+                'content' => array(
+                    'js_object' => $this->getJsObject(),
+                    'url' => $sIconImage,
+                    'id' => $iId
+                )
+            ),
+            'bx_if:show_icon_html' => array(
+                'condition' => $bIconHtml,
+                'content' => array(
+                    'icon' => $sIconHtml
+                )
+            )
+        ));
+    }
+        
 }
 
 /** @} */

+ 10 - 0
modules/boonex/forum/classes/BxForumMenuViewActions.php

@@ -70,6 +70,16 @@ class BxForumMenuViewActions extends BxBaseModTextMenuViewActions
     {
         return $this->_getMenuItemByNameActionsMore($aItem);
     }
+    
+    protected function _getMenuItemResolveDiscussion($aItem)
+    {
+        return $this->_getMenuItemByNameActions($aItem);
+    }
+    
+    protected function _getMenuItemUnresolveDiscussion($aItem)
+    {
+        return $this->_getMenuItemByNameActionsMore($aItem);
+    }
 }
 
 /** @} */

+ 78 - 4
modules/boonex/forum/classes/BxForumModule.php

@@ -157,6 +157,53 @@ class BxForumModule extends BxBaseModTextModule
 
         return $aContentInfo;
     }
+    
+    /**
+     * @page service Service Calls
+     * @section bx_forum Discussions 
+     * @subsection bx_forum-page_blocks Page Blocks
+     * @subsubsection bx_forum-categories_list categories_list
+     * 
+     * @code bx_srv('bx_forum', 'categories_list', [...]); @endcode
+     * 
+     * Get reviews rating for particular content
+     * @param $aParams additional params array, such as 'show_empty'
+     * 
+     * @see BxForumModule::serviceCategoriesList
+     */
+    /** 
+     * @ref bx_forum-categories_list "categories_list"
+     */
+    public function serviceCategoriesList($aParams = array())
+    {
+        $aCategoriest = bx_srv('system', 'categories_list', ['bx_forum_cats', ['show_empty' => true]],'TemplServiceCategory');
+        
+        $bShowEmpty = isset($aParams['show_empty']) ? (bool)$aParams['show_empty'] : false;
+    	$bShowEmptyCategories = isset($aParams['show_empty_categories']) ? (bool)$aParams['show_empty_categories'] : false;
+
+        if (!($o = BxDolCategory::getObjectInstance('bx_forum_cats')))
+            return $bShowEmpty ? MsgBox(_t('_Empty')) : '';
+
+		$aCategories = $o->getCategoriesList($bShowEmptyCategories, true);
+      
+		if(!isset($aCategories['bx_repeat:cats']))
+			return $bShowEmpty ? MsgBox(_t('_Empty')) : '';
+    
+        foreach ($aCategories['bx_repeat:cats'] as $sKey => $aCategory) {
+            $aCategories['bx_repeat:cats'][$sKey]['icon'] = '';
+            $aCategories['bx_repeat:cats'][$sKey]['class'] = $aCategory['value'] == bx_get('category') ? 'bx-forum-category-list-item-selected' : '';
+            $aCategoryData = $this->_oDb->getCategories(array('type' => 'by_category', 'category' => $aCategory['value']));
+            
+            if(isset($aCategoryData['icon']))
+               $aCategories['bx_repeat:cats'][$sKey]['icon'] = $this->_oTemplate->getImage($aCategoryData['icon'], array('class' => 'sys-icon sys-colored'));
+            
+            if(isset($aCategoryData['visible_for_levels']) && $aCategoryData['visible_for_levels'] != '' && !BxDolAcl::getInstance()->isMemberLevelInSet($aCategoryData['visible_for_levels'])){
+                unset($aCategories['bx_repeat:cats'][$sKey]);
+            }    
+        }
+        
+        return $this->_oTemplate->parseHtmlByName('category_list.html', $aCategories);
+    }
 
     /**
      * @page service Service Calls
@@ -213,7 +260,7 @@ class BxForumModule extends BxBaseModTextModule
     /** 
      * @ref bx_forum-browse_latest "browse_latest"
      */
-    public function serviceBrowseLatest($sUnitView = false, $bEmptyMessage = true, $bAjaxPaginate = true, $bShowHeader = false)
+    public function serviceBrowseLatest($sUnitView = false, $bEmptyMessage = true, $bAjaxPaginate = true, $bShowHeader = true)
     {
         $sType = 'latest';
 
@@ -286,7 +333,7 @@ class BxForumModule extends BxBaseModTextModule
     /** 
      * @ref bx_forum-browse_top "browse_top"
      */
-    public function serviceBrowseTop($sUnitView = false, $bEmptyMessage = true, $bAjaxPaginate = true, $bShowHeader = false)
+    public function serviceBrowseTop($sUnitView = false, $bEmptyMessage = true, $bAjaxPaginate = true, $bShowHeader = true)
     {
         $sType = 'top';
 
@@ -627,7 +674,7 @@ class BxForumModule extends BxBaseModTextModule
     /** 
      * @ref bx_forum-browse_category "browse_category"
      */
-    public function serviceBrowseCategory($sUnitView = false, $bEmptyMessage = true, $bAjaxPaginate = true, $bShowHeader = false)
+    public function serviceBrowseCategory($sUnitView = false, $bEmptyMessage = true, $bAjaxPaginate = true, $bShowHeader = true)
     {
         $sType = 'category';
         $iCategory = bx_process_input(bx_get('category'), BX_DATA_INT);
@@ -949,6 +996,32 @@ class BxForumModule extends BxBaseModTextModule
 
     	return $this->_checkAllowedAction('stick any entry', $aDataEntry, $isPerformAction);
     }
+    
+    public function checkAllowedResolveAnyEntry($aDataEntry, $isPerformAction = false)
+    {
+    	$CNF = &$this->_oConfig->CNF;
+
+    	if((int)$aDataEntry[$CNF['FIELD_RESOLVABLE']] != 1 || (int)$aDataEntry[$CNF['FIELD_RESOLVE']] != 0)
+    		return false;
+
+        if($aDataEntry[$CNF['FIELD_AUTHOR']] == bx_get_logged_profile_id())
+            return true;
+        
+		return $this->_checkAllowedAction('resolve any entry', $aDataEntry, $isPerformAction);
+    }
+
+    public function checkAllowedUnresolveAnyEntry($aDataEntry, $isPerformAction = false)
+    {
+    	$CNF = $this->_oConfig->CNF;
+        
+    	if((int)$aDataEntry[$CNF['FIELD_RESOLVABLE']] != 1 || (int)$aDataEntry[$CNF['FIELD_RESOLVE']] != 1)
+			return false;
+        
+        if($aDataEntry[$CNF['FIELD_AUTHOR']] == bx_get_logged_profile_id())
+            return true;
+
+    	return $this->_checkAllowedAction('resolve any entry', $aDataEntry, $isPerformAction);
+    }
 
     public function checkAllowedLockAnyEntry($aDataEntry, $isPerformAction = false)
     {
@@ -1032,7 +1105,8 @@ class BxForumModule extends BxBaseModTextModule
             return false;
 
         $oGrid->setBrowseParams($aParams);
-
+        $this->_oTemplate->addJsTranslation(array('_sys_grid_search'));
+        $this->_oTemplate->addCss(array('grid_tools.css'));
         return $oGrid->getCode($isDisplayHeader);
     }
 

+ 15 - 4
modules/boonex/forum/classes/BxForumTemplate.php

@@ -133,7 +133,7 @@ class BxForumTemplate extends BxBaseModTextTemplate
     	));
     }
 
-    function getEntryPreview($aRow)
+    function getEntryPreview($aRow, $aParams = [])
     {
         $oModule = BxDolModule::getInstance($this->MODULE);
         $CNF = &$oModule->_oConfig->CNF;
@@ -177,19 +177,30 @@ class BxForumTemplate extends BxBaseModTextTemplate
             'badges' => $oModule->serviceGetBadges($aRow[$CNF['FIELD_ID']], false, true),
             'text' => $sText,
             'bx_if:meta_main' => array(
-                'condition' => $aMetas['main'] !== false,
+                'condition' => $aMetas['main'] !== false && (!isset($aParams['show_meta_main']) || $aParams['show_meta_main']),
                 'content' => $aMetas['main']
             ),
             'bx_if:meta_counters' => array(
-                'condition' => $aMetas['counters'] !== false,
+                'condition' => $aMetas['counters'] !== false && (!isset($aParams['show_meta_counters']) || $aParams['show_meta_counters']),
                 'content' => $aMetas['counters']
             ),
             'bx_if:meta_reply' => array(
-                'condition' => $aMetas['reply'] !== false,
+                'condition' => $aMetas['reply'] !== false && (!isset($aParams['show_meta_reply']) || $aParams['show_meta_reply']),
                 'content' => $aMetas['reply']
             )
         ));
     }
+    
+    public function getJsCode($sType, $aParams = array(), $mixedWrap = true)
+    {
+        $CNF = $this->_oModule->_oConfig->CNF;
+        if ($sType == 'main'){
+            $aParams = array_merge(array(
+                'sObjNameGrid' => $CNF['OBJECT_GRID'],
+            ), $aParams);
+        }
+        return parent::getJsCode($sType, $aParams);
+    }
 
     function getAuthorDesc ($aData, $oProfile)
     {

+ 36 - 0
modules/boonex/forum/install/langs/en.xml

@@ -64,6 +64,8 @@
     <string name="_bx_forum_form_entry_input_sys_multicat"><![CDATA[Categories]]></string>
     <string name="_bx_forum_form_entry_input_multicat"><![CDATA[Categories]]></string>
     <string name="_bx_forum_form_entry_input_multicat_err"><![CDATA[Please select category]]></string>
+    <string name="_bx_forum_form_entry_input_resolvable"><![CDATA[Resolvable]]></string>
+    <string name="_bx_forum_form_entry_input_sys_resolvable"><![CDATA[Resolvable]]></string>
 
     <string name="_bx_forum_form_poll"><![CDATA[Polls]]></string>
     <string name="_bx_forum_form_poll_display_add"><![CDATA[Add Poll]]></string>
@@ -98,6 +100,7 @@
 	<string name="_bx_forum_acl_action_stick_any_entry"><![CDATA[Pin any discussion]]></string>
 	<string name="_bx_forum_acl_action_lock_any_entry"><![CDATA[Lock any discussion]]></string>
 	<string name="_bx_forum_acl_action_hide_any_entry"><![CDATA[Hide any discussion]]></string>
+    <string name="_bx_forum_acl_action_resolve_any_entry"><![CDATA[Resolve any discussion]]></string>
 
 	<string name="_bx_forum_page_title_sys_create_entry"><![CDATA[New discussion]]></string>
 	<string name="_bx_forum_page_title_create_entry"><![CDATA[New discussion]]></string>
@@ -136,6 +139,9 @@
     <string name="_bx_forum_page_title_sys_home"><![CDATA[Discussions Home]]></string>
     <string name="_bx_forum_page_title_home"><![CDATA[Discussions]]></string>
     <string name="_bx_forum_page_block_title_featured_entries"><![CDATA[Featured Discussions]]></string>
+    <string name="_bx_forum_page_block_title_featured_entries_view_showcase"><![CDATA[Featured Discussions]]></string>
+    <string name="_bx_forum_page_block_title_sys_featured_entries_view_showcase"><![CDATA[Featured Discussions (Showcase view)]]></string>
+    
     <string name="_bx_forum_page_title_sys_entries_new"><![CDATA[New Discussions]]></string>
     <string name="_bx_forum_page_title_entries_new"><![CDATA[New Discussions]]></string>
     <string name="_bx_forum_page_title_sys_entries_top"><![CDATA[Top Discussions]]></string>
@@ -240,6 +246,10 @@
     <string name="_bx_forum_menu_item_title_edit_entry"><![CDATA[Edit]]></string>
     <string name="_bx_forum_menu_item_title_system_delete_entry"><![CDATA[Delete]]></string>
     <string name="_bx_forum_menu_item_title_delete_entry"><![CDATA[Delete]]></string>
+    <string name="_bx_forum_menu_item_title_resolve_entry"><![CDATA[Resolve]]></string>
+    <string name="_bx_forum_menu_item_title_unresolve_entry"><![CDATA[Unresolve]]></string>
+    <string name="_bx_forum_menu_item_title_system_resolve_entry"><![CDATA[Resolve]]></string>
+    <string name="_bx_forum_menu_item_title_system_unresolve_entry"><![CDATA[Unresolve]]></string>
     <string name="_bx_forum_menu_item_title_system_stick_entry"><![CDATA[Pin]]></string>
     <string name="_bx_forum_menu_item_title_stick_entry"><![CDATA[Pin]]></string>
     <string name="_bx_forum_menu_item_title_system_unstick_entry"><![CDATA[Unpin]]></string>
@@ -314,6 +324,8 @@
     <string name="_bx_forum_grid_column_title_adm_author"><![CDATA[Author]]></string>
     <string name="_bx_forum_grid_column_title_title"><![CDATA[Category]]></string>
     <string name="_bx_forum_grid_column_title_visible_for_levels"><![CDATA[Visible For]]></string>
+    <string name="_bx_forum_grid_column_title_icon"><![CDATA[Icon]]></string>
+    <string name="_bx_forum_grid_action_title_edit"><![CDATA[Edit]]></string>
     <string name="_bx_forum_grid_action_title_adm_edit"><![CDATA[Edit]]></string>
     <string name="_bx_forum_grid_action_title_adm_delete"><![CDATA[Delete]]></string>
     <string name="_bx_forum_grid_action_title_adm_clear_reports"><![CDATA[Clear reports]]></string>
@@ -332,6 +344,30 @@
     <string name="_bx_forum_grid_txt_visible_for_selected"><![CDATA[Selected levels]]></string>
     <string name="_bx_forum_grid_inf_visible_for_levels"><![CDATA[Select user levels that can view this category]]></string>
     <string name="_bx_forum_grid_err_show_to"><![CDATA[Cannot update category.]]></string>
+    <string name="_bx_forum_grid_edit_popup"><![CDATA[Edit category]]></string>
+    <string name="_bx_forum_grid_err_items_icon_image_remove"><![CDATA[Cannot remove icon image: ]]></string>
+    <string name="_bx_forum_grid_err_items_icon_image"><![CDATA[Cannot process image: ]]></string>
+    <string name="_bx_forum_grid_form_txt_badges_icon"><![CDATA[Icon]]></string>
+    <string name="_bx_forum_grid_form_txt_badges_icon_image"><![CDATA[]]></string>
+    <string name="_bx_forum_grid_form_txt_badges_icon_image_new"><![CDATA[]]></string>
+    <string name="_bx_forum_grid_form_txt_badges_icon_image_old"><![CDATA[Current Icon]]></string>
+    <string name="_bx_forum_grid_form_dsc_badges_icon"><![CDATA[You may use: 1) font icon, 2) Inline SVG code, 3) Emoji]]></string>
+    <string name="_bx_forum_grid_form_dsc_badges_icon_image"><![CDATA[or upload a small image to be displayed near the link.]]></string>
+    <string name="_bx_forum_grid_form_dsc_badges_icon_image_current"><![CDATA[No icon uploaded. Text is used in menu item.]]></string>
+    <string name="_bx_forum_grid_form_btn_badges_submit"><![CDATA[Submit]]></string>
+    <string name="_bx_forum_grid_form_btn_badges_cancel"><![CDATA[Cancel]]></string>
+    
+    <string name="_bx_forum_grid_filter_resolved_all"><![CDATA[All]]></string>
+    <string name="_bx_forum_grid_filter_badges_all"><![CDATA[All]]></string>
+    <string name="_bx_forum_grid_filter_resolved_resolved"><![CDATA[Resolved]]></string>
+    <string name="_bx_forum_grid_filter_resolved_unresolved"><![CDATA[Unresolved]]></string>
+    
+    <string name="_bx_forum_grid_filter_order_recent"><![CDATA[Recent Posts]]></string>
+    <string name="_bx_forum_grid_filter_order_new"><![CDATA[New]]></string>
+    <string name="_bx_forum_grid_filter_order_top"><![CDATA[Top]]></string>
+    <string name="_bx_forum_grid_filter_order_updated"><![CDATA[Updated]]></string>
+    <string name="_bx_forum_grid_filter_order_popular"><![CDATA[Popular]]></string>
+    
     <string name="_bx_forum_grid_btn_save"><![CDATA[Save]]></string>
     <string name="_bx_forum_grid_btn_cancel"><![CDATA[Cancel]]></string>
 

+ 37 - 20
modules/boonex/forum/install/sql/enable.sql

@@ -111,10 +111,11 @@ INSERT INTO `sys_pages_blocks`(`object`, `cell_id`, `module`, `title_system`, `t
 
 -- PAGE: entries by category
 INSERT INTO `sys_objects_page`(`object`, `uri`, `title_system`, `title`, `module`, `layout_id`, `visible_for_levels`, `visible_for_levels_editable`, `url`, `meta_description`, `meta_keywords`, `meta_robots`, `cache_lifetime`, `cache_editable`, `deletable`, `override_class_name`, `override_class_file`) VALUES 
-('bx_forum_category', 'discussions-category', '_bx_forum_page_title_sys_entries_by_category', '_bx_forum_page_title_entries_by_category', @sName, 5, 2147483647, 1, 'page.php?i=discussions-category', '', '', '', 0, 1, 0, 'BxForumPageBrowse', 'modules/boonex/forum/classes/BxForumPageBrowse.php');
+('bx_forum_category', 'discussions-category', '_bx_forum_page_title_sys_entries_by_category', '_bx_forum_page_title_entries_by_category', @sName, 1, 2147483647, 1, 'page.php?i=discussions-category', '', '', '', 0, 1, 0, 'BxForumPageBrowse', 'modules/boonex/forum/classes/BxForumPageBrowse.php');
 
 INSERT INTO `sys_pages_blocks`(`object`, `cell_id`, `module`, `title_system`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `active`, `order`) VALUES 
-('bx_forum_category', 1, @sName, '_bx_forum_page_block_title_sys_entries_by_category', '_bx_forum_page_block_title_entries_by_category', 11, 2147483647, 'service', 'a:3:{s:6:"module";s:8:"bx_forum";s:6:"method";s:15:"browse_category";s:6:"params";a:1:{i:0;s:5:"table";}}', 0, 0, 1, 1);
+('bx_forum_category', 2, @sName, '_bx_forum_page_block_title_sys_entries_by_category', '_bx_forum_page_block_title_entries_by_category', 11, 2147483647, 'service', 'a:3:{s:6:"module";s:8:"bx_forum";s:6:"method";s:15:"browse_category";s:6:"params";a:1:{i:0;s:5:"table";}}', 0, 0, 1, 1),
+('bx_forum_category', 1, @sName, '', '_bx_forum_page_block_title_cats', 11, 2147483647, 'service', 'a:2:{s:6:\"module\";s:8:\"bx_forum\";s:6:\"method\";s:15:\"categories_list\";}', 0, 0, 1, 1);
 
 -- PAGE: entries by keyword
 INSERT INTO `sys_objects_page`(`object`, `uri`, `title_system`, `title`, `module`, `layout_id`, `visible_for_levels`, `visible_for_levels_editable`, `url`, `meta_description`, `meta_keywords`, `meta_robots`, `cache_lifetime`, `cache_editable`, `deletable`, `override_class_name`, `override_class_file`) VALUES 
@@ -152,16 +153,17 @@ INSERT INTO `sys_pages_blocks`(`object`, `cell_id`, `module`, `title_system`, `t
 ('bx_forum_context', 1, @sName, '_bx_forum_page_block_title_sys_entries_in_context', '_bx_forum_page_block_title_entries_in_context', 11, 2147483647, 'service', 'a:2:{s:6:\"module\";s:8:\"bx_forum\";s:6:\"method\";s:14:\"browse_context\";}', 0, 0, 1, 1);
 
 -- PAGE: module home
-INSERT INTO `sys_objects_page`(`object`, `uri`, `title_system`, `title`, `module`, `layout_id`, `visible_for_levels`, `visible_for_levels_editable`, `url`, `meta_description`, `meta_keywords`, `meta_robots`, `cache_lifetime`, `cache_editable`, `deletable`, `override_class_name`, `override_class_file`) VALUES 
-('bx_forum_home', 'discussions-home', '_bx_forum_page_title_sys_home', '_bx_forum_page_title_home', @sName, 2, 2147483647, 1, 'page.php?i=discussions-home', '', '', '', 0, 1, 0, 'BxForumPageBrowse', 'modules/boonex/forum/classes/BxForumPageBrowse.php');
+INSERT INTO `sys_objects_page`(`object`, `uri`, `title_system`, `title`, `module`, `cover`, `cover_image`, `type_id`, `layout_id`, `submenu`, `visible_for_levels`, `visible_for_levels_editable`, `url`, `meta_description`, `meta_keywords`, `meta_robots`, `cache_lifetime`, `cache_editable`, `inj_head`, `inj_footer`, `sticky_columns`, `deletable`, `override_class_name`, `override_class_file`) VALUES 
+('bx_forum_home', 'discussions-home', '_bx_forum_page_title_sys_home', '_bx_forum_page_title_home', @sName, 1, 0, 1, 6, '', 2147483647, 1, 'page.php?i=discussions-home', '', '', '', 0, 1, '', '', 0, 0, 'BxForumPageBrowse', 'modules/boonex/forum/classes/BxForumPageBrowse.php');
+
+INSERT INTO `sys_pages_blocks`(`object`, `cell_id`, `module`, `title_system`, `title`, `designbox_id`, `async`, `cache_lifetime`, `submenu`, `tabs`, `hidden_on`, `visible_for_levels`, `type`, `content`, `help`, `deletable`, `copyable`, `active`, `order`) VALUES 
+('bx_forum_home', 1, @sName, '_bx_forum_page_block_title_sys_featured_entries_view_showcase', '_bx_forum_page_block_title_featured_entries_view_showcase', 11, 0, NULL, '', 0, '', 2147483647, 'service', 'a:3:{s:6:\"module\";s:8:\"bx_forum\";s:6:\"method\";s:15:\"browse_featured\";s:6:\"params\";a:3:{s:9:\"unit_view\";s:8:\"showcase\";s:13:\"empty_message\";b:0;s:13:\"ajax_paginate\";b:0;}}', NULL, 0, 1, 1, 0),
+('bx_forum_home', 2, @sName, '', '_bx_forum_page_block_title_cats', 11, 0, NULL, '', 0, 0, 2147483647, 'service', 'a:2:{s:6:\"module\";s:8:\"bx_forum\";s:6:\"method\";s:15:\"categories_list\";}', NULL, 0, 1, 1, 0),
+('bx_forum_home', 2, @sName, '_bx_forum_page_block_title_sys_multicats', '_bx_forum_page_block_title_multicats', 11, 0, NULL, '', 0, '', 2147483647, 'service', 'a:2:{s:6:\"module\";s:8:\"bx_forum\";s:6:\"method\";s:21:\"categories_multi_list\";}', NULL, 0, 1, 0, 1),
+('bx_forum_home', 3, @sName, '', '_bx_forum_page_block_title_latest_entries', 11, 0, NULL, '', 0, '', 2147483647, 'service', 'a:3:{s:6:\"module\";s:8:\"bx_forum\";s:6:\"method\";s:13:\"browse_latest\";s:6:\"params\";a:3:{i:0;s:5:\"table\";i:1;b:1;i:2;b:0;}}', NULL, 0, 1, 1, 1),
+('bx_forum_home', 2, @sName, '', '_bx_forum_page_block_title_browse_labels', 11, 0, NULL, '', 0, '', 2147483647, 'service', 'a:3:{s:6:\"module\";s:6:\"system\";s:6:\"method\";s:13:\"browse_labels\";s:5:\"class\";s:20:\"TemplServiceMetatags\";}', NULL, 0, 1, 0, 2),
+('bx_forum_home', 2, @sName, '', '_bx_forum_page_block_title_popular_keywords', 11, 0, NULL, '', 0, '', 2147483647, 'service', 'a:4:{s:6:\"module\";s:6:\"system\";s:6:\"method\";s:14:\"keywords_cloud\";s:6:\"params\";a:2:{i:0;s:8:\"bx_forum\";i:1;s:8:\"bx_forum\";}s:5:\"class\";s:20:\"TemplServiceMetatags\";}', NULL, 0, 1, 1, 3);
 
-INSERT INTO `sys_pages_blocks`(`object`, `cell_id`, `module`, `title_system`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `active`, `order`) VALUES
-('bx_forum_home', 1, @sName, '', '_bx_forum_page_block_title_featured_entries', 11, 2147483647, 'service', 'a:3:{s:6:"module";s:8:"bx_forum";s:6:"method";s:15:"browse_featured";s:6:"params";a:4:{i:0;s:5:"table";i:1;b:0;i:2;b:1;i:3;b:0;}}', 0, 1, 1, 0),
-('bx_forum_home', 1, @sName, '', '_bx_forum_page_block_title_latest_entries', 11, 2147483647, 'service', 'a:3:{s:6:"module";s:8:"bx_forum";s:6:"method";s:13:"browse_latest";s:6:"params";a:3:{i:0;s:5:"table";i:1;b:1;i:2;b:0;}}', 0, 1, 1, 1),
-('bx_forum_home', 2, @sName, '', '_bx_forum_page_block_title_cats', 11, 2147483647, 'service', 'a:4:{s:6:"module";s:6:"system";s:6:"method";s:15:"categories_list";s:6:"params";a:2:{i:0;s:13:"bx_forum_cats";i:1;a:1:{s:10:"show_empty";b:1;}}s:5:"class";s:20:"TemplServiceCategory";}', 0, 1, 1, 0),
-('bx_forum_home', 2, @sName, '', '_bx_forum_page_block_title_popular_keywords', 11, 2147483647, 'service', 'a:4:{s:6:"module";s:6:"system";s:6:"method";s:14:"keywords_cloud";s:6:"params";a:2:{i:0;s:8:"bx_forum";i:1;s:8:"bx_forum";}s:5:"class";s:20:"TemplServiceMetatags";}', 0, 1, 1, 1),
-('bx_forum_home', 2, @sName, '', '_bx_forum_page_block_title_browse_labels', 11, 2147483647, 'service', 'a:3:{s:6:"module";s:6:"system";s:6:"method";s:13:"browse_labels";s:5:"class";s:20:"TemplServiceMetatags";}', 0, 1, 0, 0),
-('bx_forum_home', 2, @sName, '_bx_forum_page_block_title_sys_multicats', '_bx_forum_page_block_title_multicats', 11, 2147483647, 'service', 'a:2:{s:6:"module";s:8:"bx_forum";s:6:"method";s:21:"categories_multi_list";}', 0, 1, 0, 0);
 
 -- PAGE: module search
 INSERT INTO `sys_objects_page`(`object`, `uri`, `title_system`, `title`, `module`, `layout_id`, `visible_for_levels`, `visible_for_levels_editable`, `url`, `meta_description`, `meta_keywords`, `meta_robots`, `cache_lifetime`, `cache_editable`, `deletable`, `override_class_name`, `override_class_file`) VALUES 
@@ -253,6 +255,7 @@ INSERT INTO `sys_menu_sets`(`set_name`, `module`, `title`, `deletable`) VALUES
 
 INSERT INTO `sys_menu_items`(`set_name`, `module`, `name`, `title_system`, `title`, `link`, `onclick`, `target`, `icon`, `submenu_object`, `submenu_popup`, `visible_for_levels`, `active`, `copyable`, `order`) VALUES
 -- ('bx_forum_view', @sName, 'subscribe-discussion', '_bx_forum_menu_item_title_system_subscribe', '_bx_forum_menu_item_title_subscribe', 'javascript:void(0)', 'bx_conn_action(this, \'bx_forum_subscribers\', \'add\', \'{content_id}\')', '', 'check', '', 0, 2147483647, 1, 0, 1),
+('bx_forum_view', @sName, 'resolve-discussion', '_bx_forum_menu_item_title_system_resolve_entry', '_bx_forum_menu_item_title_resolve_entry', 'javascript:void(0);', '{js_object}.updateStatus(this, \'resolve\', {content_id});', '', 'check-circle', '', 0, 2147483647, 1, 0, 1),
 ('bx_forum_view', @sName, 'stick-discussion', '_bx_forum_menu_item_title_system_stick_entry', '_bx_forum_menu_item_title_stick_entry', 'javascript:void(0);', '{js_object}.updateStatus(this, \'stick\', {content_id});', '', 'thumbtack', '', 0, 2147483647, 1, 0, 2),
 ('bx_forum_view', @sName, 'lock-discussion', '_bx_forum_menu_item_title_system_lock_entry', '_bx_forum_menu_item_title_lock_entry', 'javascript:void(0);', '{js_object}.updateStatus(this, \'lock\', {content_id});', '', 'lock', '', 0, 2147483647, 1, 0, 3),
 ('bx_forum_view', @sName, 'hide-discussion', '_bx_forum_menu_item_title_system_hide_entry', '_bx_forum_menu_item_title_hide_entry', 'javascript:void(0);', '{js_object}.updateStatus(this, \'hide\', {content_id});', '', 'stop-circle', '', 0, 2147483647, 1, 0, 4),
@@ -268,6 +271,7 @@ INSERT INTO `sys_menu_sets`(`set_name`, `module`, `title`, `deletable`) 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 
 -- ('bx_forum_view_more', @sName, 'unsubscribe-discussion', '_bx_forum_menu_item_title_system_unsubscribe', '_bx_forum_menu_item_title_unsubscribe', 'javascript:void(0)', 'bx_conn_action(this, \'bx_forum_subscribers\', \'remove\', \'{content_id}\')', '', 'check', '', 2147483647, 1, 0, 1),
+('bx_forum_view_more', @sName, 'unresolve-discussion', '_bx_forum_menu_item_title_system_unresolve_entry', '_bx_forum_menu_item_title_unresolve_entry', 'javascript:void(0);', '{js_object}.updateStatus(this, \'unresolve\', {content_id});', '', 'check-circle', '', 2147483647, 1, 0, 1),
 ('bx_forum_view_more', @sName, 'unstick-discussion', '_bx_forum_menu_item_title_system_unstick_entry', '_bx_forum_menu_item_title_unstick_entry', 'javascript:void(0);', '{js_object}.updateStatus(this, \'unstick\', {content_id});', '', 'thumbtack', '', 2147483647, 1, 0, 2),
 ('bx_forum_view_more', @sName, 'unlock-discussion', '_bx_forum_menu_item_title_system_unlock_entry', '_bx_forum_menu_item_title_unlock_entry', 'javascript:void(0);', '{js_object}.updateStatus(this, \'unlock\', {content_id});', '', 'unlock', '', 2147483647, 1, 0, 3),
 ('bx_forum_view_more', @sName, 'unhide-discussion', '_bx_forum_menu_item_title_system_unhide_entry', '_bx_forum_menu_item_title_unhide_entry', 'javascript:void(0);', '{js_object}.updateStatus(this, \'unhide\', {content_id});', '', 'play-circle', '', 2147483647, 1, 0, 4),
@@ -284,6 +288,8 @@ INSERT INTO `sys_menu_sets`(`set_name`, `module`, `title`, `deletable`) VALUES
 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`, `order`) VALUES 
 -- ('bx_forum_view_actions', @sName, 'subscribe-discussion', '_bx_forum_menu_item_title_system_subscribe', '', '', '', '', '', '', '', 0, 2147483647, '', 1, 0, 10),
 -- ('bx_forum_view_actions', @sName, 'unsubscribe-discussion', '_bx_forum_menu_item_title_system_unsubscribe', '', '', '', '', '', '', '', 0, 2147483647, '', 1, 0, 20),
+('bx_forum_view_actions', @sName, 'resolve-discussion', '_bx_forum_menu_item_title_system_resolve_entry', '', '', '', '', '', '', '', 0, 2147483647, '', 1, 0, 20),
+('bx_forum_view_actions', @sName, 'unresolve-discussion', '_bx_forum_menu_item_title_system_unresolve_entry', '', '', '', '', '', '', '', 0, 2147483647, '', 1, 0, 25),
 ('bx_forum_view_actions', @sName, 'stick-discussion', '_bx_forum_menu_item_title_system_stick_entry', '', '', '', '', '', '', '', 0, 2147483647, '', 1, 0, 30),
 ('bx_forum_view_actions', @sName, 'unstick-discussion', '_bx_forum_menu_item_title_system_unstick_entry', '', '', '', '', '', '', '', 0, 2147483647, '', 1, 0, 40),
 ('bx_forum_view_actions', @sName, 'lock-discussion', '_bx_forum_menu_item_title_system_lock_entry', '', '', '', '', '', '', '', 0, 2147483647, '', 1, 0, 50),
@@ -404,8 +410,11 @@ INSERT INTO `sys_objects_grid` (`object`, `source_type`, `source`, `table`, `fie
 ('bx_forum_feature', 'Sql', 'SELECT `bx_forum_discussions`.*, `bx_forum_cmts`.`cmt_text` AS `cmt_text` %s FROM `bx_forum_discussions` LEFT JOIN `bx_forum_cmts` ON (`bx_forum_cmts`.`cmt_id` = `bx_forum_discussions`.`lr_comment_id`) %s WHERE 1 %s %s', 'bx_forum_discussions', 'id', 'lr_timestamp', '', 10, NULL, 'start', '', 'title,text,text_comments', 'auto', '', 2147483647, 'BxForumGrid', 'modules/boonex/forum/classes/BxForumGrid.php');
 
 INSERT INTO `sys_grid_fields` (`object`, `name`, `title`, `width`, `params`, `order`) VALUES
-(@sName, 'author', '', '10%', '', 1),
-(@sName, 'text', '', '90%', '', 2),
+(@sName, 'rating', '', '10%', '', 1),
+(@sName, 'category', '', '10%', '', 2),
+(@sName, 'text', '', '60%', '', 3),
+(@sName, 'participants', '', '10%', '', 4),
+(@sName, 'status', '', '10%', '', 5),
 
 ('bx_forum_favorite', 'author', '', '10%', '', 1),
 ('bx_forum_favorite', 'text', '', '90%', '', 2),
@@ -413,9 +422,6 @@ INSERT INTO `sys_grid_fields` (`object`, `name`, `title`, `width`, `params`, `or
 ('bx_forum_feature', 'author', '', '10%', '', 1),
 ('bx_forum_feature', 'text', '', '90%', '', 2);
 
-INSERT INTO `sys_grid_actions` (`object`, `type`, `name`, `title`, `icon`, `confirm`, `order`) VALUES
-(@sName, 'independent', 'add', '_bx_forum_grid_action_title_add', '', 0, 1);
-
 -- GRIDS: moderation tools
 INSERT INTO `sys_objects_grid` (`object`, `source_type`, `source`, `table`, `field_id`, `field_order`, `field_active`, `paginate_url`, `paginate_per_page`, `paginate_simple`, `paginate_get_start`, `paginate_get_per_page`, `filter_fields`, `filter_fields_translatable`, `filter_mode`, `sorting_fields`, `sorting_fields_translatable`, `visible_for_levels`, `override_class_name`, `override_class_file`) VALUES
 ('bx_forum_administration', 'Sql', 'SELECT * FROM `bx_forum_discussions` WHERE 1 ', 'bx_forum_discussions', 'id', 'added', 'status_admin', '', 20, NULL, 'start', '', 'title,text', '', 'like', 'reports', '', 192, 'BxForumGridAdministration', 'modules/boonex/forum/classes/BxForumGridAdministration.php'),
@@ -456,11 +462,14 @@ INSERT INTO `sys_objects_grid` (`object`, `source_type`, `source`, `table`, `fie
 ('bx_forum_categories', 'Array', '', '', 'category', '', '', 10, NULL, 'start', '', 'title', 'auto', '', 128, 'BxForumGridCategories', 'modules/boonex/forum/classes/BxForumGridCategories.php');
 
 INSERT INTO `sys_grid_fields` (`object`, `name`, `title`, `width`, `params`, `order`) VALUES
-('bx_forum_categories', 'title', '_bx_forum_grid_column_title_title', '60%', '', 1),
-('bx_forum_categories', 'visible_for_levels', '_bx_forum_grid_column_title_visible_for_levels', '40%', '', 2);
+('bx_forum_categories', 'icon', '_bx_forum_grid_column_title_icon', '10%', '', 1),
+('bx_forum_categories', 'title', '_bx_forum_grid_column_title_title', '50%', '', 2),
+('bx_forum_categories', 'visible_for_levels', '_bx_forum_grid_column_title_visible_for_levels', '20%', '', 3),
+('bx_forum_categories', 'actions', '', '20%', '', 4);
 
 INSERT INTO `sys_grid_actions` (`object`, `type`, `name`, `title`, `icon`, `confirm`, `order`) VALUES
-('bx_forum_categories', 'single', 'show_to', '_bx_forum_grid_action_title_show_to', '', 0, 1);
+('bx_forum_categories', 'single', 'show_to', '_bx_forum_grid_action_title_show_to', '', 0, 1),
+('bx_forum_categories', 'single', 'edit', '_bx_forum_grid_action_title_adm_edit', 'pencil-alt', 0, 2);
 
 
 -- ACL
@@ -500,6 +509,10 @@ INSERT INTO `sys_acl_actions` (`Module`, `Name`, `AdditionalParamName`, `Title`,
 (@sName, 'hide any entry', NULL, '_bx_forum_acl_action_hide_any_entry', '', 1, 3);
 SET @iIdActionEntryHideAny = LAST_INSERT_ID();
 
+INSERT INTO `sys_acl_actions` (`Module`, `Name`, `AdditionalParamName`, `Title`, `Desc`, `Countable`, `DisabledForLevels`) VALUES
+(@sName, 'resolve any entry', NULL, '_bx_forum_acl_action_resolve_any_entry', '', 1, 3);
+SET @iIdActionEntryResolveAny = LAST_INSERT_ID();
+
 SET @iUnauthenticated = 1;
 SET @iAccount = 2;
 SET @iStandard = 3;
@@ -557,7 +570,11 @@ INSERT INTO `sys_acl_matrix` (`IDLevel`, `IDAction`) VALUES
 
 -- hide any entry
 (@iModerator, @iIdActionEntryHideAny),
-(@iAdministrator, @iIdActionEntryHideAny);
+(@iAdministrator, @iIdActionEntryHideAny),
+
+-- resolve any entry
+(@iModerator, @iIdActionEntryResolveAny),
+(@iAdministrator, @iIdActionEntryResolveAny);
 
 
 -- PRIVACY 

+ 9 - 3
modules/boonex/forum/install/sql/install.sql

@@ -30,6 +30,8 @@ CREATE TABLE IF NOT EXISTS `bx_forum_discussions` (
   `featured` int(11) NOT NULL default '0',
   `stick` tinyint(4) NOT NULL DEFAULT '0',
   `lock` tinyint(4) NOT NULL DEFAULT '0',
+  `resolvable` tinyint(4) NOT NULL DEFAULT '0',
+  `resolved` tinyint(4) NOT NULL DEFAULT '0',
   `allow_view_to` varchar(16) NOT NULL DEFAULT '3',
   `status` enum('active','hidden') NOT NULL DEFAULT 'active',
   `status_admin` enum('active','hidden','pending') NOT NULL DEFAULT 'active',
@@ -41,6 +43,7 @@ CREATE TABLE IF NOT EXISTS `bx_forum_discussions` (
 CREATE TABLE IF NOT EXISTS `bx_forum_categories` (
   `category` int(11) NOT NULL default '0',
   `visible_for_levels` int(11) NOT NULL default '2147483647',
+  `icon` text NOT NULL,
   PRIMARY KEY (`category`)
 );
 
@@ -449,6 +452,7 @@ INSERT INTO `sys_form_inputs`(`object`, `module`, `name`, `value`, `values`, `ch
 ('bx_forum_search', @sName, 'author', '', '', 0, 'custom', '_bx_forum_form_search_input_sys_author', '_bx_forum_form_search_input_author', '', 0, 0, 0, '', '', '', '', '', '', '', '', 1, 0),
 ('bx_forum_search', @sName, 'category', '', '#!bx_forum_cats', 0, 'select', '_bx_forum_form_search_input_sys_category', '_bx_forum_form_search_input_category', '', 0, 0, 0, '', '', '', '', '', '', '', '', 1, 0),
 ('bx_forum_search', @sName, 'keyword', '', '', 0, 'text', '_bx_forum_form_search_input_sys_keyword', '_bx_forum_form_search_input_keyword', '', 0, 0, 0, '', '', '', '', '', '', '', '', 1, 0),
+(@sName, @sName, 'resolvable', '', '1', 0, 'switcher', '_bx_forum_form_entry_input_sys_resolvable', '_bx_forum_form_entry_input_resolvable', '', 0, 0, 0, '', '', '', '', '', '', 'Xss', '', 1, 0),
 ('bx_forum_search', @sName, 'do_submit', '_bx_forum_form_search_input_do_submit', '', 0, 'submit', '_bx_forum_form_search_input_sys_do_submit', '', '', 0, 0, 0, '', '', '', '', '', '', '', '', 1, 0);
 
 INSERT INTO `sys_form_display_inputs` (`display_name`, `input_name`, `visible_for_levels`, `active`, `order`) VALUES
@@ -462,7 +466,8 @@ INSERT INTO `sys_form_display_inputs` (`display_name`, `input_name`, `visible_fo
 ('bx_forum_entry_add', 'polls', 2147483647, 1, 8),
 ('bx_forum_entry_add', 'covers', 2147483647, 1, 9),
 ('bx_forum_entry_add', 'allow_view_to', 2147483647, 1, 10),
-('bx_forum_entry_add', 'do_submit', 2147483647, 1, 11),
+('bx_forum_entry_add', 'resolvable', 2147483647, 1, 11),
+('bx_forum_entry_add', 'do_submit', 2147483647, 1, 12),
 
 ('bx_forum_entry_edit', 'title', 2147483647, 1, 1),
 ('bx_forum_entry_edit', 'cat', 2147483647, 1, 2),
@@ -474,7 +479,8 @@ INSERT INTO `sys_form_display_inputs` (`display_name`, `input_name`, `visible_fo
 ('bx_forum_entry_edit', 'polls', 2147483647, 1, 8),
 ('bx_forum_entry_edit', 'covers', 2147483647, 1, 9),
 ('bx_forum_entry_edit', 'allow_view_to', 2147483647, 1, 10),
-('bx_forum_entry_edit', 'do_submit', 2147483647, 1, 11),
+('bx_forum_entry_edit', 'resolvable', 2147483647, 1, 11),
+('bx_forum_entry_edit', 'do_submit', 2147483647, 1, 12),
 
 ('bx_forum_entry_view', 'title', 2147483647, 1, 1),
 ('bx_forum_entry_view', 'cat', 2147483647, 1, 2),
@@ -539,7 +545,7 @@ INSERT INTO `sys_objects_vote` (`Name`, `TableMain`, `TableTrack`, `PostTimeout`
 
 -- SCORES
 INSERT INTO `sys_objects_score` (`name`, `module`, `table_main`, `table_track`, `post_timeout`, `is_on`, `trigger_table`, `trigger_field_id`, `trigger_field_author`, `trigger_field_score`, `trigger_field_cup`, `trigger_field_cdown`, `class_name`, `class_file`) VALUES 
-(@sName, @sName, 'bx_forum_scores', 'bx_forum_scores_track', '604800', '0', 'bx_forum_discussions', 'id', 'author', 'score', 'sc_up', 'sc_down', '', '');
+(@sName, @sName, 'bx_forum_scores', 'bx_forum_scores_track', '604800', '1', 'bx_forum_discussions', 'id', 'author', 'score', 'sc_up', 'sc_down', '', '');
 
 
 -- FAVORITES

+ 40 - 0
modules/boonex/forum/js/main.js

@@ -13,6 +13,8 @@ function BxForumMain(oOptions) {
     this._sObjName = oOptions.sObjName == undefined ? 'oFormMain' : oOptions.sObjName;
     this._sAnimationEffect = oOptions.sAnimationEffect == undefined ? 'fade' : oOptions.sAnimationEffect;
     this._iAnimationSpeed = oOptions.iAnimationSpeed == undefined ? 'slow' : oOptions.iAnimationSpeed;
+    this._sObjNameGrid = oOptions.sObjNameGrid;
+    this._sParamsDivider = oOptions.sParamsDivider == undefined ? '#-#' : oOptions.sParamsDivider;
 
 	var $this = this;
 	$(document).ready(function () {
@@ -56,3 +58,41 @@ BxForumMain.prototype.init = function() {
 
     oFunction();
 };
+
+BxForumMain.prototype.onChangeFilter = function (oFilter) {
+    var $this = this;
+	
+    var oFilter1 = $('#bx-grid-filter1-' + this._sObjNameGrid);
+    var sValueFilter1 = oFilter1.length > 0 ? oFilter1.val() : '';
+    
+    var oFilter2 = $('#bx-grid-filter2-' + this._sObjNameGrid);
+    var sValueFilter2 = oFilter2.length > 0 ? oFilter2.val() : '';
+    
+    var oFilter3 = $('#bx-grid-filter3-' + this._sObjNameGrid);
+    var sValueFilter3 = oFilter3.length > 0 ? oFilter3.val() : '';
+	
+    var oSearch = $('#bx-grid-search-' + this._sObjNameGrid);
+	var sValueSearch = oSearch.length > 0 ? oSearch.val() : '';
+	
+    if(sValueSearch == _t('_sys_grid_search'))
+		sValueSearch = '';
+	clearTimeout($this._iSearchTimeoutId);
+	$this._iSearchTimeoutId = setTimeout(function () {
+        glGrids[$this._sObjNameGrid].setFilter(sValueFilter1 + $this._sParamsDivider + sValueFilter2 + $this._sParamsDivider + sValueFilter3 + $this._sParamsDivider + sValueSearch, true);
+    }, 500);
+};
+
+BxForumMain.prototype.setFilter = function (sFilter, isReload) {
+
+    if (this._sFilter == sFilter)
+        return;
+
+    this._sFilter = sFilter;
+
+    if (isReload) {
+        if (sFilter.length > 0)
+            this.reload(0);
+        else
+            this.reload();
+    }
+};

+ 7 - 0
modules/boonex/forum/template/category_list.html

@@ -0,0 +1,7 @@
+<div class="bx-category-list">
+    <bx_repeat:cats>
+        <div class="bx-category-list-item bx-forum-category-list-item __class__ bx-def-round-corners bx-def-padding-sec">
+            <a href="__url__"><div class="bx-forum-icon bx-def-margin-sec-right">__icon__</div> __name__ (__num__)</a> 
+        </div>
+    </bx_repeat:cats>
+</div>

+ 4 - 0
modules/boonex/forum/template/css/grid_tools.css

@@ -0,0 +1,4 @@
+@import url(../../../../base/general/template/css/manage_tools.css);
+div.bx-grid-header div.bx-form-element-wrapper{
+    width: 150px;
+}

+ 42 - 0
modules/boonex/forum/template/css/main.css

@@ -296,3 +296,45 @@
 .bx-base-general-unit-meta ul.bx-menu-object-bx_forum_snippet_meta_counters li .cmt-counter-holder {
     line-height: normal;
 }
+
+.bx-forum-category-list-item a{
+    display: flex;
+    align-items: center;
+}
+.bx-forum-category-list-item-selected{
+    background:  #ccc;
+}
+.bx-forum-icon{
+    width: 2rem;
+    height: 2rem;
+    text-align: center;
+    line-height: 2rem;
+    font-size: 1.25rem;
+}
+.bx-forum-icon svg,
+.bx-forum-icon .sys-icon{
+    width: 2rem;
+    height: 2rem;
+    border-radius: 2rem;
+}
+.bx-forum-thumb{
+    width: 3rem;
+    height: 3rem;
+    text-align: center;
+    font-size: 2rem;
+    line-height: 2.7rem;
+}
+.bx-forum-thumb img{
+    border-radius: 500px;
+}
+.bx-forum-thumb svg,
+.bx-forum-thumb .sys-icon{
+    width: 3rem;
+    height: 3rem;
+}
+.bx-forum-grid-status{
+    display: flex;
+}
+.bx-grid-table-cell-rating{
+    vertical-align: middle;
+}

+ 4 - 4
modules/boonex/forum/template/entry-preview.html

@@ -1,8 +1,4 @@
 <div class="bx-forum-grid-preview">
-    <div class="bx-forum-gp-meta bx-forum-gpm-top bx-def-font-small">
-        <bx_if:meta_main><div class="bx-base-general-unit-meta bx-forum-gpm-main">__content__</div></bx_if:meta_main>
-        <bx_if:meta_counters><div class="bx-base-general-unit-meta bx-forum-gpm-counters bx-def-media-phone-hide">__content__</div></bx_if:meta_counters>
-    </div>
     <div class="bx-forum-gp-title bx-def-font">
     	<bx_if:show_stick><i class="sys-icon thumbtack" title="<bx_text_attribute:_bx_forum_txt_entry_sticked />"></i></bx_if:show_stick>
     	<bx_if:show_lock><i class="sys-icon lock" title="<bx_text_attribute:_bx_forum_txt_entry_locked />"></i></bx_if:show_lock>
@@ -12,4 +8,8 @@
     <div class="bx-forum-gp-meta bx-forum-gpm-bottom bx-def-font-small">
         <bx_if:meta_reply><div class="bx-base-general-unit-meta bx-forum-gpm-reply">__content__</div></bx_if:meta_reply>
     </div>
+    <div class="bx-forum-gp-meta bx-forum-gpm-top bx-def-font-small">
+        <bx_if:meta_main><div class="bx-base-general-unit-meta bx-forum-gpm-main">__content__</div></bx_if:meta_main>
+        <bx_if:meta_counters><div class="bx-base-general-unit-meta bx-forum-gpm-counters bx-def-media-phone-hide">__content__</div></bx_if:meta_counters>
+    </div>
 </div>

+ 3 - 0
modules/boonex/forum/template/images/completed.svg

@@ -0,0 +1,3 @@
+<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-check-circle-fill mr-1 color-fg-success">
+    <path fill-rule="evenodd" d="M8 16A8 8 0 108 0a8 8 0 000 16zm3.78-9.72a.75.75 0 00-1.06-1.06L6.75 9.19 5.28 7.72a.75.75 0 00-1.06 1.06l2 2a.75.75 0 001.06 0l4.5-4.5z"></path>
+</svg>

+ 3 - 0
modules/boonex/forum/template/images/idea.svg

@@ -0,0 +1,3 @@
+<svg xmlns="http://www.w3.org/2000/svg"  height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-comment mr-1">
+    <path fill-rule="evenodd" d="M2.75 2.5a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h2a.75.75 0 01.75.75v2.19l2.72-2.72a.75.75 0 01.53-.22h4.5a.25.25 0 00.25-.25v-7.5a.25.25 0 00-.25-.25H2.75zM1 2.75C1 1.784 1.784 1 2.75 1h10.5c.966 0 1.75.784 1.75 1.75v7.5A1.75 1.75 0 0113.25 12H9.06l-2.573 2.573A1.457 1.457 0 014 13.543V12H2.75A1.75 1.75 0 011 10.25v-7.5z"></path>
+</svg>

+ 3 - 0
modules/boonex/forum/template/images/uncompleted.svg

@@ -0,0 +1,3 @@
+<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-check-circle mr-1">
+    <path fill-rule="evenodd" d="M1.5 8a6.5 6.5 0 1113 0 6.5 6.5 0 01-13 0zM0 8a8 8 0 1116 0A8 8 0 010 8zm11.78-1.72a.75.75 0 00-1.06-1.06L6.75 9.19 5.28 7.72a.75.75 0 00-1.06 1.06l2 2a.75.75 0 001.06 0l4.5-4.5z"></path>
+</svg>

+ 4 - 0
modules/boonex/forum/template/status.html

@@ -0,0 +1,4 @@
+<div class="bx-forum-grid-status">
+    <img src='__icon__' class="bx-def-margin-sec-right">
+    <span>__counter__</span>
+</div>

+ 1 - 0
modules/boonex/forum/template/thumb.html

@@ -0,0 +1 @@
+<div class="bx-forum-thumb" title="__title__">__icon__</div>

+ 13 - 1
studio/template/css/general.css

@@ -184,7 +184,19 @@ div.bx-std-pmen-item:hover svg g,
 div.bx-std-pmen-item.bx-menu-tab-active svg g {
     opacity: 0.85;
 }
-
+/*--- Icons ---*/
+img.bx-item-icon,
+svg.bx-item-icon{
+    width: 32px;
+    height: 32px;
+}
+div.bx-item-icon-preview {}
+div.bx-item-icon-preview img,
+div.bx-item-icon-preview svg{
+	max-width:128px; 
+    max-height:128px;
+}
+div.adm-item-icon-preview-empty {}
 
 /**
  * Footer

+ 4 - 4
template/paginate_block.html

@@ -1,13 +1,13 @@
 <div class="bx-search-result-block-pagination">
-    <bx_if:top>
+    <bx_if:paginate_top>
         <div class="bx-def-margin-bottom">
          __paginate__
 		</div>
-    </bx_if:top>
+    </bx_if:paginate_top>
 	__content__
-	<bx_if:bottom>
+	<bx_if:paginate_bottom>
 		<div class="bx-def-margin-top">
          __paginate__
 		</div>
-    </bx_if:bottom>
+    </bx_if:paginate_bottom>
 </div>

+ 9 - 3
template/scripts/BxBaseCmts.php

@@ -693,6 +693,11 @@ class BxBaseCmts extends BxDolCmts
         ));
     }
 
+    protected function _getCounterItems($iCmtsLimit, $iCmtsStart = 0)
+    {
+        return $this->_oQuery->getCommentsBy(array('type' => 'object_id', 'object_id' => $this->getId(), 'order_way' => 'desc', 'start' => $iCmtsStart, 'per_page' => $iCmtsLimit * 4));
+    }
+    
     public function getCounter($aParams = array())
     {
         $bShowEmpty = isset($aParams['show_counter_empty']) && $aParams['show_counter_empty'] == true;
@@ -710,7 +715,7 @@ class BxBaseCmts extends BxDolCmts
             $sClass .= ' bx-btn-height';
 
         $iCmtsLimit = 5;
-        $aCmts = $this->_oQuery->getCommentsBy(array('type' => 'object_id', 'object_id' => $this->getId(), 'order_way' => 'desc', 'start' => 0, 'per_page' => $iCmtsLimit * 4));
+        $aCmts = $this->_getCounterItems($iCmtsLimit);
         $aCmts = array_reverse($aCmts);
 
         $aTmplVarsProfiles = array();
@@ -747,10 +752,11 @@ class BxBaseCmts extends BxDolCmts
                     'onclick' => $sOnclick
                 )
             ),
+            
             'content' => $this->_getCounterLabel($iCount, $aParams),
             'bx_repeat:profiles' => $aTmplVarsProfiles,
             'bx_if:show_icon' => array(
-                'condition' => $bShowEmpty || !empty($aTmplVarsProfiles),
+                'condition' => $bShowEmpty && (!isset($aParams['show_icon']) || $aParams['show_icon']),
                 'content' => array(
                     'icon' => isset($aParams['custom_icon']) && $aParams['custom_icon'] != '' ? $aParams['custom_icon'] : BxTemplFunctions::getInstanceWithTemplate($this->_oTemplate)->getFontIconAsHtml('comment', $this->_sStylePrefix . '-counter-icon sys-icon')
                 )
@@ -788,7 +794,7 @@ class BxBaseCmts extends BxDolCmts
 
     protected function _getCounterLabel($iCount, $aParams = array())
     {
-        return (int)$iCount != 0 ? _t(isset($aParams['caption']) ? $aParams['caption'] : '_cmt_txt_counter', $iCount) : _t('_cmt_txt_counter_empty');
+        return (int)$iCount != 0 ? _t(isset($aParams['caption']) ? $aParams['caption'] : '_cmt_txt_counter', $iCount) : _t(isset($aParams['caption_empty']) ? $aParams['caption_empty'] : '_cmt_txt_counter_empty').'';
     }
 
     protected function _getTmplElementBlock()

+ 4 - 4
template/scripts/BxBaseSearchResult.php

@@ -91,14 +91,14 @@ class BxBaseSearchResult extends BxDolSearchResult
     function displaySearchBox ($sContent, $sPaginate = '')
     {
 		$sContent = BxDolTemplate::getInstance()->parseHtmlByName('paginate_block.html', array(
-			'bx_if:top' => array(
-				'condition' => isset($this->aCurrent['paginate']['on_top']) && $this->aCurrent['paginate']['on_top'] == true,
+			'bx_if:paginate_top' => array(
+				'condition' => (isset($this->aCurrent['paginate']['on_top']) && $this->aCurrent['paginate']['on_top'] == true) && $sPaginate != '',
 				'content' => array(
 					'paginate' => $sPaginate
 				),
 			),
-			'bx_if:bottom' => array(
-				'condition' => !isset($this->aCurrent['paginate']['on_bottom']) || $this->aCurrent['paginate']['on_bottom'] != false,
+			'bx_if:paginate_bottom' => array(
+				'condition' => (!isset($this->aCurrent['paginate']['on_bottom']) || $this->aCurrent['paginate']['on_bottom'] != false) && $sPaginate != '',
 				'content' => array(
 					'paginate' => $sPaginate
 				),