Browse Source

Ticket #1524 - The feature itself.

AntonLV 8 years ago
parent
commit
a986e97f20

+ 1 - 1
inc/classes/BxDolMenuQuery.php

@@ -69,7 +69,7 @@ class BxDolMenuQuery extends BxDolDb
     public function getMenuItemsFromSet($sSetName)
     {
         $sQuery = $this->prepare("SELECT * FROM `sys_menu_items` WHERE `set_name` = ? ORDER BY `order` ASC", $sSetName);
-        return $this->getAll($sQuery);
+        return $this->getAllWithKey($sQuery, 'name');
     }
 }
 

+ 141 - 0
inc/js/classes/BxDolMenuMoreAuto.js

@@ -0,0 +1,141 @@
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    UnaCore UNA Core
+ * @{
+ */
+
+function BxDolMenuMoreAuto(options)
+{
+    this._sObject = options.sObject;
+    this._aHtmlIds = undefined == options.aHtmlIds ? {} : options.aHtmlIds;
+
+    this._sKeyWidth = 'bx-mma-width';
+
+    this._sClassItem = '.bx-menu-item';
+    this._sClassItemMore = this._sClassItem + '.bx-menu-item-more-auto';
+    this._sClassItemMoreSubmenu = '.bx-menu-submenu-more-auto';
+
+    this._oMenu = null;
+    this._iMenu = 0;
+    this._iParent = 0;
+    this._oItemMore = null;
+    this._iItemMore = 0;
+    this._oItemMoreSubmenu = null;
+
+    var $this = this;
+    $(document).ready(function () {
+        $this.init();
+
+        $(window).on('resize', function() {
+           $this.update();
+        });
+    });
+}
+
+BxDolMenuMoreAuto.prototype.init = function() {
+    this._getData();
+
+    this._oMenu.css('overflow', 'visible');
+
+    if(this._iMenu < this._iParent)
+        return;
+
+    this._moveToSubmenu();
+};
+
+BxDolMenuMoreAuto.prototype.update = function()
+{
+    this._getData();
+
+    if(this._iMenu > this._iParent)
+        this._moveToSubmenu();
+    if(this._iMenu < this._iParent)
+        this._moveFromSubmenu();
+};
+
+BxDolMenuMoreAuto.prototype._moveToSubmenu = function()
+{
+    var $this = this;
+
+    var bRelocateOthers = false;
+    var iWidthTotal = this._iItemMore;
+    var oSubmenuItemFirst = this._oItemMoreSubmenu.children(this._sClassItem + ':first');
+
+    this._oMenu.children(this._sClassItem + ':not(' + this._sClassItemMore + ')').each(function() {
+        var oItem = $(this);
+        var iItem = $this._getWidth(oItem);
+        if(bRelocateOthers || iWidthTotal + iItem > $this._iParent) {
+            if(!oSubmenuItemFirst.length)
+                $this._oItemMoreSubmenu.append(oItem.detach());
+            else
+                oSubmenuItemFirst.before(oItem.detach());
+            bRelocateOthers = true;
+            return;
+        }
+
+        iWidthTotal += iItem;
+    });
+
+    if(this._oItemMoreSubmenu.find('li').length)
+        this._oItemMore.show();
+   
+};
+
+BxDolMenuMoreAuto.prototype._moveFromSubmenu = function()
+{
+    var $this = this;
+
+    var bStopRelocation = false;
+    var iWidthTotal = this._iMenu;
+    this._oItemMoreSubmenu.children(this._sClassItem).each(function() {
+        if(bStopRelocation) 
+            return;
+
+        var oItem = $(this);
+        var iItem = $this._getWidth(oItem);
+        if(iWidthTotal + iItem > $this._iParent) {
+            bStopRelocation = true;
+            return;
+        }
+
+        $this._oItemMore.before(oItem.detach());
+        iWidthTotal += iItem;
+    });
+
+    if(!this._oItemMoreSubmenu.find('li').length)
+        this._oItemMore.hide();
+};
+
+BxDolMenuMoreAuto.prototype._getData = function()
+{
+    var $this = this;
+
+    this._oMenu = $('.bx-menu-object-' + this._sObject);
+    this._oItemMore = this._oMenu.find(this._sClassItemMore);
+    this._oItemMoreSubmenu = this._oItemMore.find(this._sClassItemMoreSubmenu);
+
+    this._iMenu = 0;
+    this._oMenu.children(this._sClassItem + ':visible').each(function() {
+        $this._iMenu += $this._getWidth($(this));
+    });
+    
+    this._iParent = this._oMenu.parent().width();
+
+    this._iItemMore = this._oItemMore.outerWidth(true);
+};
+
+BxDolMenuMoreAuto.prototype._getWidth = function(oItem)
+{
+    var iItem = parseInt(oItem.attr(this._sKeyWidth));
+    if(iItem)
+        return iItem;
+
+    iItem = oItem.outerWidth(true);
+    if(iItem)
+        oItem.attr(this._sKeyWidth, iItem);
+
+    return iItem;
+}
+/** @} */

+ 238 - 0
modules/base/general/classes/BxBaseModGeneralMenuViewActions.php

@@ -0,0 +1,238 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    BaseGeneral Base classes for modules
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+/**
+ * View entry social actions menu
+ */
+class BxBaseModGeneralMenuViewActions extends BxTemplMenuCustom
+{
+    protected $_sModule;
+    protected $_oModule;
+
+    protected $_oMenuAction;
+    protected $_oMenuSocialSharing;
+
+    protected $_iContentId;
+    protected $_aContentInfo;
+
+    protected $_bDynamicMode;
+    protected $_bShowAsButton;
+    protected $_bShowTitle;
+
+    public function __construct($aObject, $oTemplate = false)
+    {
+        parent::__construct($aObject, $oTemplate);
+
+        $this->_oModule = BxDolModule::getInstance($this->_sModule);
+
+        $this->setContentId(bx_process_input(bx_get('id'), BX_DATA_INT));
+
+        $this->_oMenuActions = null;
+        $this->_oMenuSocialSharing = null;
+
+        $this->_bShowAsButton = true;
+        $this->_bShowTitles = false;
+    }
+
+    public function setContentId($iContentId)
+    {
+        $this->_iContentId = (int)$iContentId;
+
+        $this->_aContentInfo = $this->_oModule->_oDb->getContentInfoById($this->_iContentId);
+        if($this->_aContentInfo)
+            $this->addMarkers(array('content_id' => (int)$this->_iContentId));
+    }
+
+    protected function _getMenuItemEditPost($aItem)
+    {
+        return $this->_getMenuItemByNameActions($aItem);
+    }
+
+    protected function _getMenuItemDeletePost($aItem)
+    {
+        return $this->_getMenuItemByNameActions($aItem);
+    }
+
+    protected function _getMenuItemView($aItem)
+    {
+        $CNF = &$this->_oModule->_oConfig->CNF;
+
+        $oObject = !empty($CNF['OBJECT_VIEWS']) ? BxDolView::getObjectInstance($CNF['OBJECT_VIEWS'], $this->_iContentId) : false;
+        if(!$oObject || !$oObject->isEnabled())
+            return '';
+
+    	return $oObject->getElementBlock(array(
+            'dynamic_mode' => $this->_bDynamicMode,
+            'show_do_view_as_button' => $this->_bShowAsButton,
+            'show_do_view_label' => $this->_bShowTitle
+        ));
+    }
+
+    protected function _getMenuItemComment($aItem)
+    {
+        $CNF = &$this->_oModule->_oConfig->CNF;
+
+        $oObject = !empty($CNF['OBJECT_COMMENTS']) ? BxTemplCmts::getObjectInstance($CNF['OBJECT_COMMENTS'], $this->_iContentId) : false;
+        if(!$oObject || !$oObject->isEnabled())
+            return '';
+
+        return $oObject->getElementBlock(array(
+            'dynamic_mode' => $this->_bDynamicMode,
+            'show_do_comment_as_button' => $this->_bShowAsButton,
+            'show_do_comment_label' => $this->_bShowTitle
+        ));
+    }
+
+    protected function _getMenuItemVote($aItem)
+    {
+        $CNF = &$this->_oModule->_oConfig->CNF;
+
+        $oObject = !empty($CNF['OBJECT_VOTES']) ? BxDolVote::getObjectInstance($CNF['OBJECT_VOTES'], $this->_iContentId) : false;
+        if(!$oObject || !$oObject->isEnabled())
+            return '';
+
+    	return $oObject->getElementBlock(array(
+            'dynamic_mode' => $this->_bDynamicMode,
+            'show_do_vote_as_button' => $this->_bShowAsButton,
+            'show_do_vote_label' => $this->_bShowTitle
+        ));
+    }
+    
+    protected function _getMenuItemScore($aItem)
+    {
+        $CNF = &$this->_oModule->_oConfig->CNF;
+
+        $oObject = !empty($CNF['OBJECT_SCORES']) ? BxDolScore::getObjectInstance($CNF['OBJECT_SCORES'], $this->_iContentId) : false;
+        if(!$oObject || !$oObject->isEnabled())
+            return '';
+
+    	return $oObject->getElementBlock(array(
+            'dynamic_mode' => $this->_bDynamicMode,
+            'show_do_vote_as_button' => $this->_bShowAsButton,
+            'show_do_vote_label' => $this->_bShowTitle
+        ));
+    }
+
+    protected function _getMenuItemFavorite($aItem)
+    {
+        $CNF = &$this->_oModule->_oConfig->CNF;
+
+        $oObject = !empty($CNF['OBJECT_FAVORITES']) ? BxDolFavorite::getObjectInstance($CNF['OBJECT_FAVORITES'], $this->_iContentId) : false;
+        if(!$oObject || !$oObject->isEnabled())
+            return '';
+
+    	return $oObject->getElementBlock(array(
+            'dynamic_mode' => $this->_bDynamicMode,
+            'show_do_favorite_as_button' => $this->_bShowAsButton,
+            'show_do_favorite_label' => $this->_bShowTitle
+        ));
+    }
+
+    protected function _getMenuItemFeature($aItem)
+    {
+        $CNF = &$this->_oModule->_oConfig->CNF;
+
+        $oObject = !empty($CNF['OBJECT_FEATURED']) ? BxDolFeature::getObjectInstance($CNF['OBJECT_FEATURED'], $this->_iContentId) : false;
+        if(!$oObject || !$oObject->isEnabled())
+            return '';
+
+    	return $oObject->getElementBlock(array(
+            'dynamic_mode' => $this->_bDynamicMode,
+            'show_do_feature_as_button' => $this->_bShowAsButton,
+            'show_do_feature_label' => $this->_bShowTitle
+        ));
+    }
+
+    protected function _getMenuItemRepost($aItem)
+    {
+        $CNF = &$this->_oModule->_oConfig->CNF;
+
+        if(!BxDolRequest::serviceExists('bx_timeline', 'get_repost_element_block'))
+            return '';
+
+    	return BxDolService::call('bx_timeline', 'get_repost_element_block', array(bx_get_logged_profile_id(), $this->_oModule->_oConfig->getName(), 'added', $this->_iContentId, array(
+            'show_do_repost_as_button' => $this->_bShowAsButton,
+            'show_do_repost_text' => $this->_bShowTitle
+        )));
+    }
+
+    protected function _getMenuItemReport($aItem)
+    {
+        $CNF = &$this->_oModule->_oConfig->CNF;
+
+        $oObject = !empty($CNF['OBJECT_REPORTS']) ? BxDolReport::getObjectInstance($CNF['OBJECT_REPORTS'], $this->_iContentId) : false;
+        if(!$oObject || !$oObject->isEnabled())
+            return '';
+
+    	return $oObject->getElementBlock(array(
+            'dynamic_mode' => $this->_bDynamicMode,
+            'show_do_report_as_button' => $this->_bShowAsButton,
+            'show_do_report_label' => $this->_bShowTitle
+        ));
+    }
+
+    protected function _getMenuItemMoreAuto($aItem)
+    {
+        $aItem['class_link'] = (!empty($aItem['class_link']) ? $aItem['class_link'] . ' ' : '') . 'bx-btn';
+        
+        return parent::_getMenuItemMoreAuto($aItem);
+    }
+
+    protected function _getMenuItemSocialSharingFacebook($aItem)
+    {
+        return $this->_getMenuItemByNameSocialSharing($aItem);
+    }
+
+    protected function _getMenuItemSocialSharingGoogleplus($aItem)
+    {
+        return $this->_getMenuItemByNameSocialSharing($aItem);
+    }
+
+    protected function _getMenuItemSocialSharingTwitter($aItem)
+    {
+        return $this->_getMenuItemByNameSocialSharing($aItem);
+    }
+
+    protected function _getMenuItemSocialSharingPinterest($aItem)
+    {
+        return $this->_getMenuItemByNameSocialSharing($aItem);
+    }
+
+    protected function _getMenuItemByNameActions($aItem)
+    {
+        $CNF = &$this->_oModule->_oConfig->CNF;
+
+        if(empty($this->_oMenuActions)) {
+            if(empty($CNF['OBJECT_MENU_ACTIONS_VIEW_ENTRY']))
+                return '';
+
+            $this->_oMenuActions = BxDolMenu::getObjectInstance($CNF['OBJECT_MENU_ACTIONS_VIEW_ENTRY']);
+            $this->_oMenuActions->setContentId($this->_iContentId);
+        }
+
+        return $this->_oMenuActions->getCodeItem($aItem['name']);
+    }
+
+    protected function _getMenuItemByNameSocialSharing($aItem)
+    {
+        if(empty($this->_oMenuSocialSharing)) {
+            $this->_oMenuSocialSharing = BxDolMenu::getObjectInstance('sys_social_sharing');
+            $this->_oMenuSocialSharing->addMarkers(array_merge($this->_aMarkers, array(
+                'id' => $this->_iContentId,
+                'module' => $this->_oModule->_oConfig->getName(),
+            )));
+        }
+
+        return $this->_oMenuSocialSharing->getCodeItem($aItem['name']);
+    }
+}
+
+/** @} */

+ 91 - 38
modules/base/general/classes/BxBaseModGeneralModule.php

@@ -559,9 +559,58 @@ class BxBaseModGeneralModule extends BxDolModule
     /**
      * Entry actions and social sharing block
      */
-    public function serviceEntityAllActions ($iContentId = 0)
+    public function serviceEntityAllActions ($iContentId = 0, $aParams = array())
     {
-        return $this->_oTemplate->entryAllActions($this->serviceEntityActions($iContentId), $this->serviceEntitySocialSharing($iContentId));
+        $CNF = &$this->_oConfig->CNF;
+
+        $iContentId = $this->_getContent($iContentId, false);
+        if($iContentId === false)
+            return false;
+
+        if(!empty($CNF['OBJECT_MENU_ACTIONS_VIEW_ENTRY_ALL'])) {
+            $sEntryTitle = !empty($aParams['entry_title']) ? $aParams['entry_title'] : '';
+            if(empty($sEntryTitle) && !empty($CNF['FIELD_TITLE']) && !empty($aContentInfo[$CNF['FIELD_TITLE']]))
+                $sEntryTitle = $aContentInfo[$CNF['FIELD_TITLE']];
+            
+            $sEntryUrl = !empty($aParams['entry_url']) ? $aParams['entry_url'] : '';
+            if(empty($sEntryUrl) && !empty($CNF['URI_VIEW_ENTRY']))
+                $sEntryUrl = BX_DOL_URL_ROOT . BxDolPermalinks::getInstance()->permalink('page.php?i=' . $CNF['URI_VIEW_ENTRY'] . '&id=' . $iContentId);
+
+            $iEntryThumb = !empty($aParams['entry_thumb']) ? (int)$aParams['entry_thumb'] : 0;
+            if(empty($iEntryThumb) && !empty($CNF['FIELD_THUMB']) && !empty($aContentInfo[$CNF['FIELD_THUMB']]))
+                $iEntryThumb = (int)$aContentInfo[$CNF['FIELD_THUMB']];
+
+            $sObjectStorage = !empty($aParams['object_storage']) ? $aParams['object_storage'] : false;
+            if(empty($sObjectStorage) && !empty($CNF['OBJECT_STORAGE']))
+                $sObjectStorage = $CNF['OBJECT_STORAGE'];
+            
+            $sObjectTranscoder = !empty($aParams['object_transcoder']) ? $aParams['object_transcoder'] : false;
+
+            $aMarkers = array();
+            if(!empty($sEntryTitle))
+                $aMarkers['title'] = $sEntryTitle;
+
+            if(!empty($sEntryUrl))
+                $aMarkers['url'] = $sEntryUrl;
+
+            if(!empty($iEntryThumb)) {
+                if(!empty($sObjectTranscoder))
+                    $o = BxDolTranscoder::getObjectInstance($sObjectTranscoder);
+                else if(!empty($sObjectStorage))
+                    $o = BxDolStorage::getObjectInstance($sObjectStorage);
+
+                $sImageUrl = $o ? $o->getFileUrlById($iEntryThumb) : '';
+                if(!empty($sImageUrl))
+                    $aMarkers['img_url'] = $sImageUrl;
+            }
+
+            $oSocialActions = BxDolMenu::getObjectInstance($CNF['OBJECT_MENU_ACTIONS_VIEW_ENTRY_ALL']);
+            $oSocialActions->addMarkers($aMarkers);
+            return $this->_oTemplate->entryAllActions($oSocialActions->getCode());
+        }
+
+        //TODO: Remove this at the end.
+        return $this->serviceEntityActions($iContentId) . $this->serviceEntitySocialSharing($iContentId);
     }
 
     /**
@@ -580,6 +629,7 @@ class BxBaseModGeneralModule extends BxDolModule
     /**
      * Entry social sharing block
      */
+    //TODO: Update to work with Social Sharing menu only.
     public function serviceEntitySocialSharing ($iContentId = 0)
     {
         $mixedContent = $this->_getContent($iContentId);
@@ -1347,11 +1397,43 @@ class BxBaseModGeneralModule extends BxDolModule
 
     protected function _entitySocialSharing ($iId, $aParams = array())
     {
+        $CNF = &$this->_oConfig->CNF;
+
         $bShowAsButton = !isset($aParams['show_as_button']) || $aParams['show_as_button'] === true;
 
         $sUrl = !empty($aParams['uri_view_entry']) ? BxDolPermalinks::getInstance()->permalink('page.php?i=' . $aParams['uri_view_entry'] . '&id=' . $iId) : '';
         $sTitle = !empty($aParams['title']) ? $aParams['title'] : '';
 
+        $aMarkers = array();
+        $bSocialSharing = isset($aParams['social_sharing']) ? (bool)$aParams['social_sharing'] : true;
+        if($bSocialSharing) {
+            $aMarkers = array(
+                'id' => $iId,                           //TODO: Can be removed later
+                'module' => $this->_aModule['name'],    //TODO: Can be removed later
+                'url' => BX_DOL_URL_ROOT . $sUrl,
+                'title' => $sTitle,
+            );
+
+            $iIdThumb = isset($aParams['id_thumb']) ? (int)$aParams['id_thumb'] : 0;
+            if ($iIdThumb) {
+                if(!empty($aParams['object_transcoder']))
+                    $o = BxDolTranscoder::getObjectInstance($aParams['object_transcoder']);
+                else if(!empty($aParams['object_storage']))
+                    $o = BxDolStorage::getObjectInstance($aParams['object_storage']);
+
+                $sImgUrl = $o ? $o->getFileUrlById($iIdThumb) : '';
+                if($sImgUrl)
+                    $aMarkers['img_url'] = $sImgUrl;
+            }
+        }
+
+        //TODO: Rebuild using menus engine when it will be ready for such elements like Vote, Share, etc.
+        //--- Views
+        $sViews = '';
+        $oViews = !empty($aParams['object_view']) ? BxDolView::getObjectInstance($aParams['object_view'], $iId) : false;
+        if ($oViews && $oViews->isEnabled())
+            $sViews = $oViews->getElementBlock(array('show_do_view_as_button' => $bShowAsButton));
+
         //--- Comments
         $sComments = '';
         $oComments = !empty($aParams['object_comments']) ? BxTemplCmts::getObjectInstance($aParams['object_comments'], $iId) : false;
@@ -1371,30 +1453,6 @@ class BxBaseModGeneralModule extends BxDolModule
             ));
         }
 
-        $aCustomParams = array();
-        $iIdThumb = isset($aParams['id_thumb']) ? (int)$aParams['id_thumb'] : 0;
-        $bSocialSharing = isset($aParams['social_sharing']) ? (bool)$aParams['social_sharing'] : true;
-        if ($iIdThumb && $bSocialSharing) {
-            if(!empty($aParams['object_transcoder']))
-                $o = BxDolTranscoder::getObjectInstance($aParams['object_transcoder']);
-            else if(!empty($aParams['object_storage']))
-                $o = BxDolStorage::getObjectInstance($aParams['object_storage']);
-
-            $sImgUrl = $o ? $o->getFileUrlById($iIdThumb) : '';
-            if($sImgUrl)
-                $aCustomParams = array (
-                    'img_url' => $sImgUrl,
-                    'img_url_encoded' => rawurlencode($sImgUrl),
-                );
-        }
-
-        //TODO: Rebuild using menus engine when it will be ready for such elements like Vote, Share, etc.
-        //--- Views
-        $sViews = '';
-        $oViews = !empty($aParams['object_view']) ? BxDolView::getObjectInstance($aParams['object_view'], $iId) : false;
-        if ($oViews && $oViews->isEnabled())
-            $sViews = $oViews->getElementBlock(array('show_do_view_as_button' => $bShowAsButton));
-
         //--- Votes
         $sVotes = '';
         $oVotes = !empty($aParams['object_vote']) ? BxDolVote::getObjectInstance($aParams['object_vote'], $iId) : false;
@@ -1431,16 +1489,11 @@ class BxBaseModGeneralModule extends BxDolModule
         if ($oReport)
             $sReport = $oReport->getElementBlock(array('show_do_report_as_button' => $bShowAsButton));
 
-        $sSocial = '';
+        $sSocialSharing = '';
         if($bSocialSharing) {
             $oSocial = BxDolMenu::getObjectInstance('sys_social_sharing');
-            $oSocial->addMarkers(array_merge(array(
-                'id' => $iId,
-            	'module' => $this->_aModule['name'],
-            	'url' => BX_DOL_URL_ROOT . $sUrl,
-            	'title' => $sTitle,
-            ), $aCustomParams));
-            $sSocial = $oSocial->getCode();
+            $oSocial->addMarkers($aMarkers);
+            $sSocialSharing = $oSocial->getCode();
         }
 
         if(empty($sComments)  && empty($sViews) && empty($sVotes) && empty($sScores) && empty($sFavorites)  && empty($sFeatured) && empty($sRepost) && empty($sReport) && empty($sSocial))
@@ -1448,14 +1501,14 @@ class BxBaseModGeneralModule extends BxDolModule
 
         return $this->_oTemplate->parseHtmlByName('entry-share.html', array(
             'comments' => $sComments,
-        	'view' => $sViews,
+            'view' => $sViews,
             'vote' => $sVotes,
-        	'score' => $sScores,
+            'score' => $sScores,
             'favorite' => $sFavorites,
             'feature' => $sFeatured,
             'repost' => $sRepost,
-        	'report' => $sReport,
-            'social' => $sSocial,
+            'report' => $sReport,
+            'social' => $sSocialSharing,
         ));
         //TODO: Rebuild using menus engine when it will be ready for such elements like Vote, Repost, etc.
     }

+ 3 - 4
modules/base/general/classes/BxBaseModGeneralTemplate.php

@@ -192,14 +192,13 @@ class BxBaseModGeneralTemplate extends BxDolModuleTemplate
     	));
     }
 
-    function entryAllActions ($sActionsEntity, $sActionsSocial)
+    function entryAllActions($sActions)
     {
-        if(empty($sActionsEntity) && empty($sActionsSocial))
+        if(empty($sActions))
             return '';
 
         return $this->parseHtmlByName('entry-all-actions.html', array (
-            'actions_entity' => $sActionsEntity,
-            'actions_social' => $sActionsSocial,
+            'actions' => $sActions
         ));
     }
 

+ 58 - 6
modules/base/general/template/css/main.css

@@ -4,7 +4,9 @@
     margin-top:0;
 }
 
-.bx-base-general-entity-actions-all {
+
+/* view entry: actions */
+.bx-base-general-entity-actions ul.bx-menu-hor {
     position: relative;
     display: -webkit-flex;
     display: flex;
@@ -12,15 +14,65 @@
     align-items: center;
     -webkit-justify-content: flex-start;
     justify-content: flex-start;
+    -webkit-flex-wrap: wrap;
+    flex-wrap: wrap;
+}
+.bx-base-general-entity-actions ul.bx-menu-hor.bx-menu-more-auto {
+    -webkit-flex-wrap: nowrap;
+    flex-wrap: nowrap;
 }
-.bx-base-general-entity-actions-all > * {
-    margin-left: 16px;
-    margin-left: 1rem;
+.bx-base-general-entity-actions .bx-menu-hor li.bx-menu-item {
+    white-space: nowrap;
 }
-.bx-base-general-entity-actions-all > *:first-child {
-    margin-left: 0;
+.bx-base-general-entity-actions .bx-menu-hor li.bx-menu-item .sys-icon {
+    vertical-align: text-top;
+}
+.bx-base-general-entity-actions .bx-menu-hor li.bx-menu-item .cmt-element-holder,
+.bx-base-general-entity-actions .bx-menu-hor li.bx-menu-item .cmt-counter-holder,
+.bx-base-general-entity-actions .bx-menu-hor li.bx-menu-item .bx-view-element-holder,
+.bx-base-general-entity-actions .bx-menu-hor li.bx-menu-item .bx-view-counter-holder,
+.bx-base-general-entity-actions .bx-menu-hor li.bx-menu-item .bx-vote-element-holder, 
+.bx-base-general-entity-actions .bx-menu-hor li.bx-menu-item .bx-vote-counter-holder, 
+.bx-base-general-entity-actions .bx-menu-hor li.bx-menu-item .bx-score-element-holder, 
+.bx-base-general-entity-actions .bx-menu-hor li.bx-menu-item .bx-score-counter-holder, 
+.bx-base-general-entity-actions .bx-menu-hor li.bx-menu-item .bx-favorite-element-holder,
+.bx-base-general-entity-actions .bx-menu-hor li.bx-menu-item .bx-favorite-counter-holder,
+.bx-base-general-entity-actions .bx-menu-hor li.bx-menu-item .bx-report-element-holder,
+.bx-base-general-entity-actions .bx-menu-hor li.bx-menu-item .bx-report-counter-holder,
+.bx-base-general-entity-actions .bx-menu-hor li.bx-menu-item .bx-tl-repost-element-holder,
+.bx-base-general-entity-actions .bx-menu-hor li.bx-menu-item .bx-tl-repost-counter-holder {
+    float: none;
+    display: inline-block;
+    vertical-align: top;
+}
+.bx-base-general-entity-actions .bx-menu-hor li.bx-menu-item .cmt-counter-holder,
+.bx-base-general-entity-actions .bx-menu-hor li.bx-menu-item .bx-view-counter-holder,
+.bx-base-general-entity-actions .bx-menu-hor li.bx-menu-item .bx-vote-counter-holder, 
+.bx-base-general-entity-actions .bx-menu-hor li.bx-menu-item .bx-score-counter-holder, 
+.bx-base-general-entity-actions .bx-menu-hor li.bx-menu-item .bx-favorite-counter-holder,
+.bx-base-general-entity-actions .bx-menu-hor li.bx-menu-item .bx-report-counter-holder,
+.bx-base-general-entity-actions .bx-menu-hor li.bx-menu-item .bx-tl-repost-counter-holder {
+    line-height: normal;
+}
+.bx-base-general-entity-actions .cmt,
+.bx-base-general-entity-actions .bx-view,
+.bx-base-general-entity-actions .bx-vote,
+.bx-base-general-entity-actions .bx-score,
+.bx-base-general-entity-actions .bx-favorite,
+.bx-base-general-entity-actions .bx-feature,
+.bx-base-general-entity-actions .bx-report,
+.bx-base-general-entity-actions .bx-tl-repost,
+.bx-base-general-entity-actions .bx-menu-btns-hor.bx-menu-object-sys_social_sharing {
+    position: relative;
+    float: none;
+    display: inline-block;
+    vertical-align: top;
+
+    margin: 0;
+    padding: 0;
 }
 
+/* TODO: Remove this at the end */
 .bx-base-general-entity-share .bx-base-general-comments,
 .bx-base-general-entity-share .bx-view,
 .bx-base-general-entity-share .bx-vote,

+ 1 - 3
modules/base/general/template/entry-all-actions.html

@@ -1,3 +1 @@
-<div class="bx-base-general-entity-actions-all">
-    __actions_entity____actions_social__
-</div>
+<div class="bx-base-general-entity-actions">__actions__</div>

+ 4 - 4
modules/base/text/classes/BxBaseModTextMenuViewActions.php

@@ -10,13 +10,13 @@
  */
 
 /**
- * View entry actions menu in popup
+ * View entry social actions menu
  */
-class BxBaseModTextMenuViewActions extends BxBaseModTextMenuView
+class BxBaseModTextMenuViewActions extends BxBaseModGeneralMenuViewActions
 {
-    protected function getMenuItemsRaw ()
+    public function __construct($aObject, $oTemplate = false)
     {
-        return $this->_getMenuItemsCombined ();
+        parent::__construct($aObject, $oTemplate);
     }
 }
 

+ 15 - 0
modules/boonex/english/data/langs/system/en.xml

@@ -1549,6 +1549,9 @@
 	<string name="_cmt_txt_sample_comment_single"><![CDATA[comment]]></string>
 	<string name="_cmt_txt_sample_reply_to"><![CDATA[reply to comment]]></string>
 	<string name="_cmt_txt_n_comments"><![CDATA[{0} comments]]></string>
+        <string name="_cmt_txt_do"><![CDATA[Comment]]></string>
+        <string name="_cmt_txt_counter"><![CDATA[{0}]]></string>
+	<string name="_cmt_txt_counter_empty"><![CDATA[Comment]]></string>
 	<string name="_copyright"><![CDATA[&copy; {0} Company]]></string>
 	<string name="_delete"><![CDATA[delete]]></string>
 	<string name="_error occured"><![CDATA[Error occurred]]></string>
@@ -2249,6 +2252,18 @@ If it is not enabled then please consider implement this optimization, since it
 	<string name="_sys_menu_item_title_system_set_acl_level"><![CDATA[Set membership]]></string>
 	<string name="_sys_menu_item_title_system_studio"><![CDATA[Studio]]></string>
 	<string name="_sys_menu_item_title_system_subscriptions"><![CDATA[Subscriptions]]></string>
+        <string name="_sys_menu_title_view_actions"><![CDATA[View Actions]]></string>
+        <string name="_sys_menu_set_title_view_actions"><![CDATA[View Actions]]></string>
+        <string name="_sys_menu_item_title_system_va_comment"><![CDATA[Comment]]></string>
+        <string name="_sys_menu_item_title_system_va_view"><![CDATA[View]]></string>
+        <string name="_sys_menu_item_title_system_va_vote"><![CDATA[Vote (for)]]></string>
+        <string name="_sys_menu_item_title_system_va_score"><![CDATA[Vote (for/against)]]></string>
+        <string name="_sys_menu_item_title_system_va_favorite"><![CDATA[Favorite]]></string>
+        <string name="_sys_menu_item_title_system_va_feature"><![CDATA[Feature]]></string>
+        <string name="_sys_menu_item_title_system_va_repost"><![CDATA[Repost]]></string>
+        <string name="_sys_menu_item_title_system_va_report"><![CDATA[Report]]></string>
+        <string name="_sys_menu_item_title_system_va_more_auto"><![CDATA[More]]></string>
+        <string name="_sys_menu_item_title_va_more_auto"><![CDATA[]]></string>
 	<string name="_sys_menu_item_title_system_social_sharing_facebook"><![CDATA[Share in Facebook]]></string>
     <string name="_sys_menu_item_title_system_social_sharing_googleplus"><![CDATA[Share in Google Plus]]></string>
     <string name="_sys_menu_item_title_system_social_sharing_twitter"><![CDATA[Share in Twitter]]></string>

+ 16 - 1
modules/boonex/russian/data/langs/system/ru.xml

@@ -1547,6 +1547,9 @@
 	<string name="_cmt_txt_sample_comment_single"><![CDATA[комментарий]]></string>
 	<string name="_cmt_txt_sample_reply_to"><![CDATA[ответ на комментарий]]></string>
 	<string name="_cmt_txt_n_comments"><![CDATA[{0} комментариев]]></string>	
+        <string name="_cmt_txt_do"><![CDATA[Комментировать]]></string>
+        <string name="_cmt_txt_counter"><![CDATA[{0}]]></string>
+	<string name="_cmt_txt_counter_empty"><![CDATA[Комментировать]]></string>
 	<string name="_copyright"><![CDATA[&copy; {0} Компания]]></string>
 	<string name="_delete"><![CDATA[удалить]]></string>
 	<string name="_error occured"><![CDATA[Произошла ошибка]]></string>
@@ -2248,7 +2251,19 @@
 	<string name="_sys_menu_item_title_system_set_acl_level"><![CDATA[Назначить членство]]></string>
 	<string name="_sys_menu_item_title_system_studio"><![CDATA[Студия]]></string>
 	<string name="_sys_menu_item_title_system_subscriptions"><![CDATA[Подписки]]></string>
-	<string name="_sys_menu_item_title_system_social_sharing_facebook"><![CDATA[Поделиться в Facebook]]></string>
+        <string name="_sys_menu_title_view_actions"><![CDATA[Просмотр - Действия]]></string>
+        <string name="_sys_menu_set_title_view_actions"><![CDATA[Просмотр - Действия]]></string>
+        <string name="_sys_menu_item_title_system_va_comment"><![CDATA[Комментировать]]></string>
+	<string name="_sys_menu_item_title_system_va_view"><![CDATA[Посмотреть]]></string>
+        <string name="_sys_menu_item_title_system_va_vote"><![CDATA[Проголосовать (за)]]></string>
+        <string name="_sys_menu_item_title_system_va_score"><![CDATA[Проголосовать (за/против)]]></string>
+        <string name="_sys_menu_item_title_system_va_favorite"><![CDATA[В избранное]]></string>
+        <string name="_sys_menu_item_title_system_va_feature"><![CDATA[В продвинутые]]></string>
+        <string name="_sys_menu_item_title_system_va_repost"><![CDATA[Сделать репост]]></string>
+        <string name="_sys_menu_item_title_system_va_report"><![CDATA[Пожаловаться]]></string>
+        <string name="_sys_menu_item_title_system_va_more_auto"><![CDATA[Еще]]></string>
+        <string name="_sys_menu_item_title_va_more_auto"><![CDATA[]]></string>
+        <string name="_sys_menu_item_title_system_social_sharing_facebook"><![CDATA[Поделиться в Facebook]]></string>
     <string name="_sys_menu_item_title_system_social_sharing_googleplus"><![CDATA[Поделиться в Google Plus]]></string>
     <string name="_sys_menu_item_title_system_social_sharing_twitter"><![CDATA[Поделиться в Twitter]]></string>
     <string name="_sys_menu_item_title_system_social_sharing_pinterest"><![CDATA[Поделиться в Pinterest]]></string>

+ 49 - 0
template/css/menu.css

@@ -578,6 +578,55 @@ ul.bx-menu-btns-hor li:last-child .bx-btn {
     margin-right: 1.25rem;
 }
 
+
+/*--- Custom Menu with More Auto ---*/
+.bx-menu-custom.bx-menu-hor.bx-menu-more-auto,
+.bx-menu-custom.bx-menu-hor.bx-menu-submenu-more-auto {
+    position: relative;
+    display: -webkit-flex;
+    display: flex;
+    -webkit-align-items: center;
+    align-items: center;
+    -webkit-justify-content: flex-start;
+    justify-content: flex-start;
+}
+.bx-menu-custom.bx-menu-hor.bx-menu-more-auto {
+    -webkit-flex-wrap: nowrap;
+    flex-wrap: nowrap;
+
+    overflow: hidden;
+}
+.bx-menu-custom.bx-menu-hor.bx-menu-submenu-more-auto {
+    -webkit-flex-wrap: wrap;
+    flex-wrap: wrap;
+
+    min-width: 18rem;
+}
+.bx-menu-custom.bx-menu-hor.bx-menu-more-auto .bx-menu-item {
+    position: relative;
+    display: block;
+
+    margin: 8px;
+    margin: 0.5rem;
+}
+.bx-menu-custom.bx-menu-hor.bx-menu-more-auto .bx-menu-item.bx-menu-item-more-auto > span {
+    display: block;
+    margin: 0;
+}
+.bx-menu-custom.bx-menu-hor.bx-menu-more-auto .bx-menu-item > a:last-child,
+.bx-menu-custom.bx-menu-hor.bx-menu-more-auto .bx-menu-item > a.bx-btn:last-child,
+.bx-menu-custom.bx-menu-hor.bx-menu-more-auto .bx-menu-item > span:last-child,
+.bx-menu-custom.bx-menu-hor.bx-menu-more-auto .bx-menu-item:last-child > a,
+.bx-menu-custom.bx-menu-hor.bx-menu-more-auto .bx-menu-item:last-child > a.bx-btn,
+.bx-menu-custom.bx-menu-hor.bx-menu-more-auto .bx-menu-item:last-child > span {
+    margin-right: 0;
+}
+.bx-menu-custom.bx-menu-hor.bx-menu-more-auto .bx-menu-item.bx-menu-item-more-auto {
+    display: none;
+}
+
+
+
 /*--- Vertical (Vertical Custom) Menus (in Popup) ---*/
 .bx-popup .bx-menu-custom-ver li a {
     position: relative;

+ 5 - 0
template/menu_buttons_hor_item.html

@@ -0,0 +1,5 @@
+<a class="bx-btn bx-def-margin-right" href="__link__" target="__target__" onclick="__onclick__">
+    <bx_if:image><img style="background-image:url(__icon_url__)" src="<bx_icon_url:spacer.gif />" /></bx_if:image>
+    <bx_if:icon><i class="sys-icon __icon__"></i></bx_if:icon>
+    <bx_if:title><u>__title__</u></bx_if:title>
+</a>

+ 2 - 1
template/menu_custom_hor.html

@@ -1,5 +1,6 @@
-<ul class="bx-menu-custom bx-menu-hor bx-menu-hor-inline bx-menu-object-__object__ bx-clearfix">
+<ul class="bx-menu-custom bx-menu-hor bx-menu-hor-inline<bx_if:show_more_auto_class> bx-menu-more-auto</bx_if:show_more_auto_class> bx-menu-object-__object__ bx-clearfix">
     <bx_repeat:menu_items>
         <li class="bx-menu-item bx-menu-item-__name____class__">__item__</li>
     </bx_repeat:menu_items>
 </ul>
+__js_code__

+ 2 - 2
template/menu_custom_item.html

@@ -1,5 +1,5 @@
-<span class="bx-def-margin-thd-topbottom">
-    <a href="__link__" target="__target__" onclick="__onclick__" title="__title_attr__">
+<span class="__class_wrp__ bx-def-margin-thd-topbottom">
+    <a class="__class_link__" href="__link__" target="__target__" onclick="__onclick__" title="__title_attr__">
         <bx_if:icon><i class="sys-icon __icon__"></i></bx_if:icon>
         <bx_if:image><img style="background-image:url(__icon_url__)" src="<bx_icon_url:spacer.gif />" /></bx_if:image>
         <bx_if:title><span class="bx-def-margin-sec-left-auto">__title__</span></bx_if:title>

+ 2 - 0
template/menu_custom_item_more.html

@@ -0,0 +1,2 @@
+__item__
+__popup__

+ 3 - 0
template/menu_custom_item_more_popup.html

@@ -0,0 +1,3 @@
+<div class="bx-def-padding">
+    <ul class="bx-menu-custom bx-menu-hor bx-menu-submenu-more-auto bx-clearfix">__content__</ul>
+</div>

+ 4 - 0
template/menu_icon_buttons_hor_item.html

@@ -0,0 +1,4 @@
+<a class="bx-btn bx-def-margin-right" href="__link__" target="__target__" onclick="__onclick__" <bx_if:title>title="__title_attr__"</bx_if:title>>
+    <bx_if:image><img style="background-image:url(__icon_url__)" src="<bx_icon_url:spacer.gif />" /></bx_if:image>
+    <bx_if:icon><i class="sys-icon __icon__"></i></bx_if:icon>
+</a>

+ 37 - 6
template/scripts/BxBaseMenu.php

@@ -46,6 +46,22 @@ class BxBaseMenu extends BxDolMenu
 
         return $s;
     }
+    
+    public function getCodeItem ($sName)
+    {
+        if(empty($sName))
+            return '';
+
+        $sCode = $this->_oTemplate->getHtml(str_replace('.html', '_item.html', $this->_aObject['template']));
+        if(empty($sCode))
+            return '';
+
+        $mixedTmplVars = $this->getMenuItem($sName);
+        if($mixedTmplVars === false)
+            return '';
+
+        return $this->_oTemplate->parseHtmlByContent($sCode, $mixedTmplVars);
+    }
 
     /**
      * Get template variables array
@@ -60,23 +76,38 @@ class BxBaseMenu extends BxDolMenu
     }
 
     /**
-     * Get menu items array, which are ready to pass to template.
-     * @return array
+     * Get menu items array, which is ready to pass to menu template. 
+     * @return array or false
      */
     public function getMenuItems ()
     {
         if (!isset($this->_aObject['menu_items']))
             $this->_aObject['menu_items'] = $this->getMenuItemsRaw ();
 
-		$aItems = array();
+        $aItems = array();
         foreach ($this->_aObject['menu_items'] as $aItem) {
-        	$aItem = $this->_getMenuItem ($aItem);
-        	if($aItem !== false)
-            	$aItems[] = $aItem;
+            $aItem = $this->_getMenuItem ($aItem);
+            if($aItem !== false)
+                $aItems[] = $aItem;
         }
 
         return $aItems;
     }
+    
+    /**
+     * Get menu item array, which is ready to pass to whole menu or 
+     * single menu item template. May return false if single menu item 
+     * is requested but cannot be shown by circumstances.
+     * @return array or false
+     */
+    public function getMenuItem ($sName)
+    {
+        if (!isset($this->_aObject['menu_items']))
+            $this->_aObject['menu_items'] = $this->getMenuItemsRaw ();
+
+        if(!empty($sName))
+            return $this->_getMenuItem($this->_aObject['menu_items'][$sName]);
+    }
 
     /**
      * Get menu items array, this is just a wrapper for DB function for make it easier to override.

+ 115 - 15
template/scripts/BxBaseMenuCustom.php

@@ -8,51 +8,151 @@
  * @{
  */
 
+define('BX_DEF_MENU_CUSTOM_ITEM_MORE_AUTO', 'more-auto');
+
 class BxBaseMenuCustom extends BxTemplMenu
 {
     protected static $_sTmplContentCustomItem;
 
+    protected $_sTmplNameCustomItemMore;
+    protected $_sTmplNameCustomItemMorePopup;
+
+    protected $_bAutoMore;
+    
+    protected $_aHtmlIds;
+
     public function __construct($aObject, $oTemplate = false)
     {
         parent::__construct($aObject, $oTemplate);
 
         if(empty(self::$_sTmplContentCustomItem))
             self::$_sTmplContentCustomItem = $this->_oTemplate->getHtml('menu_custom_item.html');
+
+        $this->_sTmplNameCustomItemMore = 'menu_custom_item_more.html';
+        $this->_sTmplNameCustomItemMorePopup = 'menu_custom_item_more_popup.html';
+
+        $this->_bAutoMore = false;
+
+        $sPrefix = str_replace('_', '-', $this->_sObject);
+        $this->_aHtmlIds = array(
+            'more_auto_popup' => $sPrefix . '-ma-popup',
+        );
+    }
+
+    public function getCode ()
+    {
+        $sResult = parent::getCode();
+
+        if($this->_bAutoMore)
+            $this->_oTemplate->addJs(array('BxDolMenuMoreAuto.js'));
+
+        return $sResult;
+    }
+
+    public function getMenuItems()
+    {
+        $aResult = parent::getMenuItems();
+
+        $sItem = BX_DEF_MENU_CUSTOM_ITEM_MORE_AUTO;
+        if(!empty($this->_aObject['menu_items'][$sItem]) && is_array($this->_aObject['menu_items'][$sItem]) && (int)$this->_aObject['menu_items'][$sItem]['active'] == 1)
+            $this->_bAutoMore = true;
+
+        return $aResult;
+    }
+
+    protected function _getTemplateVars()
+    {
+        $aResult = array_merge(parent::_getTemplateVars(), array(
+            'bx_if:show_more_auto_class' => array(
+                'condition' => $this->_bAutoMore,
+                'content' => array()
+            ),
+            'js_code' => $this->_bAutoMore ? $this->_getJsCodeMoreAuto() : ''
+        ));
+
+        return $aResult;
+    }
+
+    protected function _getJsCodeMoreAuto()
+    {
+        $aParams = array(
+            'sObject' => $this->_sObject
+        );
+        return $this->_oTemplate->_wrapInTagJsCode("var oMenuMoreAuto = new BxDolMenuMoreAuto(" . json_encode($aParams) . ");");
     }
 
     protected function _getMenuItem ($aItem)
     {
     	if (isset($aItem['active']) && !$aItem['active'])
-			return false;
+            return false;
 
-		if (isset($aItem['visible_for_levels']) && !$this->_isVisible($aItem))
-        	return false;
+        if (isset($aItem['visible_for_levels']) && !$this->_isVisible($aItem))
+            return false;
 
     	$sMethod = '_getMenuItem' . str_replace(' ', '', ucwords(str_replace('-', ' ', $aItem['name'])));
 
     	if(!method_exists($this, $sMethod)) {
-    		$aItem = parent::_getMenuItem($aItem);
-    		if($aItem === false)
-    			return false;
+            $aItem = parent::_getMenuItem($aItem);
+            if($aItem === false)
+                return false;
 
-			$sItem = $this->_getMenuItemDefault($aItem);
+            $sItem = $this->_getMenuItemDefault($aItem);
     	}
     	else
-    		$sItem = $this->$sMethod($aItem);
+            $sItem = $this->$sMethod($aItem);
 
     	if(empty($sItem))
-    		return false;
+            return false;
+
+        return array(
+            'name' => $aItem['name'],
+            'class' => $this->_isSelected($aItem) ? ' bx-menu-tab-active' : '',
+            'item' => $sItem
+        );
+    }
 
-		return array(
-		    'name' => $aItem['name'],
-			'class' => $this->_isSelected($aItem) ? ' bx-menu-tab-active' : '',
-			'item' => $sItem
-		);
+    protected function _getMenuItemMoreAuto ($aItem)
+    {
+        $sPopup = $this->_aHtmlIds['more_auto_popup'];
+
+        $aItem['onclick'] = "$(this).parents('li:first').find('#" . $sPopup . "').dolPopup({pointer: {el: $(this)}, moveToDocRoot: false});";
+
+        $aItem = parent::_getMenuItem($aItem);
+        if($aItem === false)
+            return false;
+
+        return $this->_oTemplate->parseHtmlByName($this->_getTmplNameItemMore(), array(
+            'item' => $this->_getMenuItemDefault($aItem),
+            'popup' => BxTemplFunctions::getInstance()->transBox($sPopup, $this->_oTemplate->parseHtmlByName($this->_getTmplNameItemMorePopup(), array(
+                'content' => ''
+            )), true)
+        ));
     }
 
     protected function _getMenuItemDefault ($aItem)
     {
-        return $this->_oTemplate->parseHtmlByContent(self::$_sTmplContentCustomItem, $aItem);
+        if(!isset($aItem['class_wrp']))
+            $aItem['class_wrp'] = '';
+
+        if(!isset($aItem['class_link']))
+            $aItem['class_link'] = '';
+
+        return $this->_oTemplate->parseHtmlByContent($this->_getTmplContentCustomItem(), $aItem);
+    }
+
+    protected function _getTmplNameItemMore()
+    {
+        return $this->_sTmplNameCustomItemMore;
+    }
+
+    protected function _getTmplNameItemMorePopup()
+    {
+        return $this->_sTmplNameCustomItemMorePopup;
+    }
+
+    protected function _getTmplContentCustomItem()
+    {
+        return self::$_sTmplContentCustomItem;
     }
 }
 

+ 2 - 1
template/scripts/BxBaseMenuSocialSharing.php

@@ -14,7 +14,8 @@ class BxBaseMenuSocialSharing extends BxTemplMenu
 {
     protected $_aNeedEncode = array(
     	'url' => 'url_encoded',
-    	'title' => 'title_encoded'
+    	'title' => 'title_encoded',
+        'img_url' => 'img_url_encoded'
     );
 
     public function __construct ($aObject, $oTemplate)