AntonLV 10 лет назад
Родитель
Сommit
aa514747ad

+ 21 - 0
inc/classes/BxDolMenu.php

@@ -197,6 +197,27 @@ class BxDolMenu extends BxDolFactory implements iBxDolFactoryObject, iBxDolRepla
         return true;
     }
 
+    /**
+     * Check if the menu is visible. The menu is visible if at least one menu item is visible.
+     * @return boolean
+     */
+    public function isVisible()
+    {
+    	if(!isset($this->_aObject['menu_items']))
+			$this->_aObject['menu_items'] = $this->_oQuery->getMenuItems();
+
+    	$bVisible = false;
+    	foreach ($this->_aObject['menu_items'] as $a) {
+    		if((isset($a['active']) && !$a['active']) || (isset($a['visible_for_levels']) && !$this->_isVisible($a)))
+				continue;
+			
+			$bVisible = true;
+			break;
+    	}
+
+    	return $bVisible;
+    }
+
     /**
      * Set selected menu item for current menu object only.
      * @param $sModule menu item module to set as selected

+ 24 - 0
modules/base/general/classes/BxBaseModGeneralModule.php

@@ -657,6 +657,30 @@ class BxBaseModGeneralModule extends BxDolModule
         return $oFavorite;
     }
 
+	public function getUserId()
+    {
+        return isLogged() ? bx_get_logged_profile_id() : 0;
+    }
+
+    public function getUserIp()
+    {
+        return getVisitorIP();
+    }
+
+    public function getUserInfo($iUserId = 0)
+    {
+        $oProfile = BxDolProfile::getInstance($iUserId);
+        if (!$oProfile)
+            $oProfile = BxDolProfileUndefined::getInstance();
+
+        return array(
+            $oProfile->getDisplayName(),
+            $oProfile->getUrl(),
+            $oProfile->getThumb(),
+            $oProfile->getUnit()
+        );
+    }
+
     // ====== PROTECTED METHODS
     protected function _isModerator ($isPerformAction = false)
     {

+ 1 - 25
modules/base/notifications/classes/BxBaseModNotificationsModule.php

@@ -21,7 +21,7 @@ define('BX_BASE_MOD_NTFS_TYPE_PUBLIC', 'public');
 /**
  * Base module class.
  */
-class BxBaseModNotificationsModule extends BxDolModule
+class BxBaseModNotificationsModule extends BxBaseModGeneralModule
 {
 	public $_iOwnerId;
 
@@ -91,30 +91,6 @@ class BxBaseModNotificationsModule extends BxDolModule
     	return $this->_iOwnerId;
     }
 
-	public function getUserId()
-    {
-        return isLogged() ? bx_get_logged_profile_id() : 0;
-    }
-
-    public function getUserIp()
-    {
-        return getVisitorIP();
-    }
-
-    public function getUserInfo($iUserId = 0)
-    {
-        $oProfile = BxDolProfile::getInstance($iUserId);
-        if (!$oProfile)
-            $oProfile = BxDolProfileUndefined::getInstance();
-
-        return array(
-            $oProfile->getDisplayName(),
-            $oProfile->getUrl(),
-            $oProfile->getThumb(),
-            $oProfile->getUnit()
-        );
-    }
-
 	protected function _updateModuleData($sAction, $sModuleUri)
     {
     	$sMethod = $this->_oConfig->getHandlersMethod();

+ 9 - 0
modules/base/text/classes/BxBaseModTextMenu.php

@@ -14,6 +14,7 @@
  */
 class BxBaseModTextMenu extends BxBaseModGeneralMenuView
 {
+    protected $_iContentId;
     protected $_aContentInfo;
 
     public function __construct($aObject, $oTemplate = false)
@@ -21,6 +22,14 @@ class BxBaseModTextMenu extends BxBaseModGeneralMenuView
         parent::__construct($aObject, $oTemplate);
     }
 
+    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));
+    }
 }
 
 /** @} */

+ 2 - 6
modules/base/text/classes/BxBaseModTextMenuView.php

@@ -17,12 +17,8 @@ class BxBaseModTextMenuView extends BxBaseModTextMenu
     public function __construct($aObject, $oTemplate = false)
     {
         parent::__construct($aObject, $oTemplate);
-
-        $iContentId = bx_process_input(bx_get('id'), BX_DATA_INT);
-
-        $this->_aContentInfo = $this->_oModule->_oDb->getContentInfoById($iContentId);
-        if ($this->_aContentInfo)
-            $this->addMarkers(array('content_id' => (int)$iContentId));
+ 
+        $this->setContentId(bx_process_input(bx_get('id'), BX_DATA_INT));
     }
 }
 

+ 6 - 1
modules/boonex/market/classes/BxMarketConfig.php

@@ -25,7 +25,7 @@ class BxMarketConfig extends BxBaseModTextConfig
         $this->CNF = array (
 
             // module icon
-            'ICON' => 'file-text col-red3',
+            'ICON' => 'shopping-cart col-green3',
 
             // database tables
             'TABLE_ENTRIES' => $aModule['db_prefix'] . 'products',
@@ -95,6 +95,8 @@ class BxMarketConfig extends BxBaseModTextConfig
             'OBJECT_STORAGE' => 'bx_market_photos',
         	'OBJECT_STORAGE_FILES' => 'bx_market_files',
             'OBJECT_IMAGES_TRANSCODER_PREVIEW' => 'bx_market_preview',
+        	'OBJECT_IMAGES_TRANSCODER_ICON' => 'bx_market_icon',
+        	'OBJECT_IMAGES_TRANSCODER_THUMB' => 'bx_market_thumb',
         	'OBJECT_IMAGES_TRANSCODER_COVER' => 'bx_market_cover',
         	'OBJECT_IMAGES_TRANSCODER_SCREENSHOT' => 'bx_market_screenshot',
             'OBJECT_IMAGES_TRANSCODER_GALLERY' => 'bx_market_gallery',
@@ -116,7 +118,9 @@ class BxMarketConfig extends BxBaseModTextConfig
             'OBJECT_FORM_ENTRY_DISPLAY_EDIT' => 'bx_market_entry_edit',
             'OBJECT_FORM_ENTRY_DISPLAY_DELETE' => 'bx_market_entry_delete',
             'OBJECT_MENU_ACTIONS_VIEW_ENTRY' => 'bx_market_view', // actions menu on view entry page
+            'OBJECT_MENU_ACTIONS_VIEW_ENTRY_POPUP' => 'bx_market_view_popup', // actions menu from view entry page but created for popup submenu
             'OBJECT_MENU_ACTIONS_MY_ENTRIES' => 'bx_market_my', // actions menu on my entries page
+            'OBJECT_MENU_ACTIONS_SNIPPET' => 'bx_market_snippet', // actions menu for entry snippet
             'OBJECT_MENU_SUBMENU' => 'bx_market_submenu', // main module submenu
             'OBJECT_MENU_SUBMENU_VIEW_ENTRY' => 'bx_market_view_submenu', // view entry submenu
             'OBJECT_MENU_SUBMENU_VIEW_ENTRY_MAIN_SELECTION' => 'products-home', // first item in view entry submenu from main module submenu
@@ -132,6 +136,7 @@ class BxMarketConfig extends BxBaseModTextConfig
                     'create-product' => 'checkAllowedAdd',
                 ),
                 'bx_market_view' => $aMenuItems2Methods,
+                'bx_market_view_popup' => $aMenuItems2Methods,
             ),
 
             // global settings

+ 61 - 0
modules/boonex/market/classes/BxMarketMenuSnippetActions.php

@@ -0,0 +1,61 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Market Market
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+class BxMarketMenuSnippetActions extends BxBaseModTextMenu
+{
+    protected $_sModule;
+    protected $_oModule;
+
+    protected $_iContentId;
+    
+    public function __construct($aObject, $oTemplate = false)
+    {
+        parent::__construct($aObject, $oTemplate);
+
+        $this->_sModule = 'bx_market';
+        $this->_oModule = BxDolModule::getInstance($this->_sModule);
+    }
+
+    /**
+     * Check if menu items is visible.
+     * @param $a menu item array
+     * @return boolean
+     */
+    protected function _isVisible ($a)
+    {
+        if(!parent::_isVisible($a))
+            return false;
+
+        $sCheckFuncName = '';
+        $aCheckFuncParams = array();
+        switch ($a['name']) {
+            case 'snippet-more':
+            	$sCheckFuncName = '_isVisibleMore';
+            	break;
+        }
+
+        if(!$sCheckFuncName || !method_exists($this, $sCheckFuncName))
+            return true;
+
+        return call_user_func_array(array($this, $sCheckFuncName), $aCheckFuncParams) === true;
+    }
+
+    protected function _isVisibleMore()
+    {
+        $CNF = &$this->_oModule->_oConfig->CNF;
+
+        $oMenu = BxDolMenu::getObjectInstance($CNF['OBJECT_MENU_ACTIONS_VIEW_ENTRY_POPUP']);
+        $oMenu->setContentId($this->_iContentId);
+    	return $oMenu->isVisible();
+    }
+}
+
+/** @} */

+ 1 - 1
modules/boonex/market/classes/BxMarketSearchResult.php

@@ -21,7 +21,7 @@ class BxMarketSearchResult extends BxBaseModTextSearchResult
             'object_metatags' => 'bx_market',
             'title' => _t('_bx_market_page_title_browse'),
             'table' => 'bx_market_products',
-            'ownFields' => array('id', 'title', 'text', 'price_single', 'price_recurring', 'duration_recurring', 'thumb', 'author', 'added'),
+            'ownFields' => array('id', 'title', 'text', 'price_single', 'price_recurring', 'duration_recurring', 'thumb', 'cover', 'author', 'added'),
             'searchFields' => array(),
             'restriction' => array(
                 'author' => array('value' => '', 'field' => 'author', 'operator' => '='),

+ 123 - 24
modules/boonex/market/classes/BxMarketTemplate.php

@@ -30,7 +30,7 @@ class BxMarketTemplate extends BxBaseModTextTemplate
 
     public function entryRating($aData)
     {
-        $CNF = &BxDolModule::getInstance($this->MODULE)->_oConfig->CNF;
+        $CNF = &$this->getModule()->_oConfig->CNF;
 
     	$sVotes = '';
         $oVotes = BxDolVote::getObjectInstance($CNF['OBJECT_VOTES'], $aData['id']);
@@ -63,7 +63,7 @@ class BxMarketTemplate extends BxBaseModTextTemplate
 
     public function setCover($aData)
     {
-		$CNF = &BxDolModule::getInstance($this->MODULE)->_oConfig->CNF;
+		$CNF = &$this->getModule()->_oConfig->CNF;
 
 		if(empty($aData[$CNF['FIELD_COVER']]))
 			return;
@@ -73,33 +73,39 @@ class BxMarketTemplate extends BxBaseModTextTemplate
         	return;
 
         //--- Get Cover image URL
-        $oImagesTranscoder = BxDolTranscoderImage::getObjectInstance($CNF['OBJECT_IMAGES_TRANSCODER_COVER']);
-		if(empty($oImagesTranscoder))
+        $oTranscoderCover = BxDolTranscoderImage::getObjectInstance($CNF['OBJECT_IMAGES_TRANSCODER_COVER']);
+		if(empty($oTranscoderCover))
 			return;
 
-		$sCoverUrl = $oImagesTranscoder->getFileUrl($aData[$CNF['FIELD_COVER']]);
+		$sCoverUrl = $oTranscoderCover->getFileUrl($aData[$CNF['FIELD_COVER']]);
 		if(empty($sCoverUrl))
 			return;
 
 		//--- Get Thumbnail image URL
-		$oImagesTranscoder = BxDolTranscoderImage::getObjectInstance($CNF['OBJECT_IMAGES_TRANSCODER_PREVIEW']);
-		if(empty($oImagesTranscoder))
-			return;
+		$sThumbnailUrl = '';
+		$bThumbnailUrl = false;
+		if(!empty($aData[$CNF['FIELD_THUMB']])) {
+		    $oTranscoderThumbnail = BxDolTranscoderImage::getObjectInstance($CNF['OBJECT_IMAGES_TRANSCODER_THUMB']);
+    		if($oTranscoderThumbnail)
+    			$sThumbnailUrl = $oTranscoderThumbnail->getFileUrl($aData[$CNF['FIELD_THUMB']]);
 
-		$sThumbnailUrl = $oImagesTranscoder->getFileUrl($aData[$CNF['FIELD_THUMB']]);
-		if(empty($sThumbnailUrl))
-			return;
+            $bThumbnailUrl = !empty($sThumbnailUrl);
+		}
 
 		$oCover = BxDolCover::getInstance($this);
 		$oCover->setCoverImageUrl($sCoverUrl);
 		$oCover->set(array_merge($mixedOptions, array(
 			'bx_if:image' => array (
-                'condition' => true,
-                'content' => array('icon_url' => $sThumbnailUrl),
+                'condition' => $bThumbnailUrl,
+                'content' => array(
+                	'icon_url' => $sThumbnailUrl
+		        ),
             ),
             'bx_if:icon' => array (
-                'condition' => false,
-                'content' => array(),
+                'condition' => !$bThumbnailUrl,
+                'content' => array(
+                    'icon' => $CNF['ICON']
+                ),
             ),
             'bx_if:bg' => array (
                 'condition' => true,
@@ -110,7 +116,7 @@ class BxMarketTemplate extends BxBaseModTextTemplate
 
     public function getScreenshots($aData)
     {
-    	$oModule = BxDolModule::getInstance($this->MODULE);
+    	$oModule = $this->getModule();
 
     	$CNF = &$oModule->_oConfig->CNF;
     	$aPhotos = $oModule->serviceGetScreenshots($aData[$CNF['FIELD_ID']]);
@@ -161,7 +167,7 @@ class BxMarketTemplate extends BxBaseModTextTemplate
 
     public function getGhostTemplateFile($oForm, $aContentInfo)
     {
-    	$CNF = BxDolModule::getInstance($this->MODULE)->_oConfig->CNF;
+    	$CNF = &$this->getModule()->_oConfig->CNF;
 
     	return $this->parseHtmlByName('form_ghost_template_file.html', array (
                 'name' => $oForm->aInputs[$CNF['FIELD_FILE']]['name'],
@@ -179,11 +185,51 @@ class BxMarketTemplate extends BxBaseModTextTemplate
 
     protected function getUnit ($aData, $aParams = array())
     {
-    	$CNF = &BxDolModule::getInstance($this->MODULE)->_oConfig->CNF;
+        $oModule = $this->getModule();
+    	$CNF = &$oModule->_oConfig->CNF;
 
     	$aUnit = parent::getUnit($aData, $aParams);
         $oPayment = BxDolPayments::getInstance();
 
+        //--- Author Info
+        list($sAuthorName, $sAuthorUrl, $sAuthorIcon) = $oModule->getUserInfo($aData[$CNF['FIELD_AUTHOR']]);
+        $bAuthorIcon = !empty($sAuthorIcon);      
+
+        //--- Main Info
+        $sUrl = BX_DOL_URL_ROOT . BxDolPermalinks::getInstance()->permalink('page.php?i=' . $CNF['URI_VIEW_ENTRY'] . '&id=' . $aData[$CNF['FIELD_ID']]);
+        $sLinkMore = ' <a title="' . bx_html_attribute(_t('_sys_read_more', $aData[$CNF['FIELD_TITLE']])) . '" href="' . $sUrl . '"><i class="sys-icon ellipsis-h"></i></a>';
+        $sSummary = strmaxtextlen($aData[$CNF['FIELD_TEXT']], (int)getParam($CNF['PARAM_CHARS_SUMMARY']), $sLinkMore);
+        $sSummaryPlain = BxTemplFunctions::getInstance()->getStringWithLimitedLength(strip_tags($sSummary), (int)getParam($CNF['PARAM_CHARS_SUMMARY_PLAIN']));
+
+        //--- Icon Info
+        $sIconUrl = '';
+        if(!empty($CNF['FIELD_THUMB']) && $aData[$CNF['FIELD_THUMB']]) {
+            $oImagesTranscoder = BxDolTranscoderImage::getObjectInstance($CNF['OBJECT_IMAGES_TRANSCODER_ICON']);
+            if($oImagesTranscoder)
+                $sIconUrl = $oImagesTranscoder->getFileUrl($aData[$CNF['FIELD_THUMB']]);
+
+            if(empty($sIconUrl)) {
+                $oImagesTranscoder = BxDolTranscoderImage::getObjectInstance($CNF['OBJECT_IMAGES_TRANSCODER_THUMB']);
+                if($oImagesTranscoder)
+                    $sIconUrl = $oImagesTranscoder->getFileUrl($aData[$CNF['FIELD_THUMB']]);
+            }
+        }
+
+        //--- Cover Info
+        $sCoverUrl = '';
+        if(!empty($CNF['FIELD_COVER']) && $aData[$CNF['FIELD_COVER']]) {
+            $oImagesTranscoder = BxDolTranscoderImage::getObjectInstance($CNF['OBJECT_IMAGES_TRANSCODER_COVER']);
+            if($oImagesTranscoder)
+                $sCoverUrl = $oImagesTranscoder->getFileUrl($aData[$CNF['FIELD_COVER']]);
+
+            if(empty($sCoverUrl)) {
+                $oImagesTranscoder = BxDolTranscoderImage::getObjectInstance($CNF['OBJECT_IMAGES_TRANSCODER_GALLERY']);
+                if($oImagesTranscoder)
+                    $sCoverUrl = $oImagesTranscoder->getFileUrl($aData[$CNF['FIELD_COVER']]);
+            }
+        }
+
+        //--- Price Single
     	$bTmplVarsSingle = (float)$aData[$CNF['FIELD_PRICE_SINGLE']] != 0;
     	$aTmplVarsSingle = array();
     	if($bTmplVarsSingle) {
@@ -192,14 +238,15 @@ class BxMarketTemplate extends BxBaseModTextTemplate
     			list($sJsCode, $sSingleOnclick) = $aJsSingle;
     			
 	    		$aTmplVarsSingle = array(
-	    			'entry_price_single_onclick' => $sSingleOnclick,
-					'entry_price_single' => _t('_bx_market_txt_price_single', $this->_aCurrency['sign'], $aData[$CNF['FIELD_PRICE_SINGLE']])
+	    			'price_single_onclick' => $sSingleOnclick,
+					'price_single' => _t('_bx_market_txt_price_single', $this->_aCurrency['sign'], $aData[$CNF['FIELD_PRICE_SINGLE']])
 				);
     		}
     		else 
     			$bTmplVarsSingle = false;
     	}
 
+    	//--- Price Recurring
     	$bTmplVarsRecurring = (float)$aData[$CNF['FIELD_PRICE_RECURRING']] != 0;
     	$aTmplVarsRecurring = array();
     	if($bTmplVarsRecurring) {
@@ -208,20 +255,72 @@ class BxMarketTemplate extends BxBaseModTextTemplate
 				list($sJsCode, $sRecurringOnclick) = $aJsRecurring;
 
 	        	$aTmplVarsRecurring = array(
-	        		'entry_price_recurring_onclick' => $sRecurringOnclick,
-					'entry_price_recurring' => _t('_bx_market_txt_price_recurring', $this->_aCurrency['sign'], $aData[$CNF['FIELD_PRICE_RECURRING']], _t('_bx_market_txt_per_' . $aData[$CNF['FIELD_DURATION_RECURRING']] . '_short'))
+	        		'price_recurring_onclick' => $sRecurringOnclick,
+					'price_recurring' => _t('_bx_market_txt_price_recurring', $this->_aCurrency['sign'], $aData[$CNF['FIELD_PRICE_RECURRING']], _t('_bx_market_txt_per_' . $aData[$CNF['FIELD_DURATION_RECURRING']] . '_short'))
 				);
         	}
         	else 
         		$bTmplVarsRecurring = false;
     	}
 
-    	$oVotes = BxDolVote::getObjectInstance($CNF['OBJECT_VOTES'], $aData['id']);
+    	$sActions = '';
+    	$oActions = BxDolMenu::getObjectInstance($CNF['OBJECT_MENU_ACTIONS_SNIPPET']);
+    	if($oActions) {
+    	    $oActions->setContentId($aData[$CNF['FIELD_ID']]);
+    	    $sActions = $oActions->getCode();
+    	}
+
+    	$sVotes = '';
+    	$oVotes = BxDolVote::getObjectInstance($CNF['OBJECT_VOTES'], $aData[$CNF['FIELD_ID']]);
         if($oVotes)
 			$sVotes = $oVotes->getElementBlock(array('show_counter' => false));
 
     	$aUnit = array_merge($aUnit, array(
-    		'entry_votes' => $sVotes,
+    	    'actions' => $sActions,
+    	    'bx_if:show_author_icon' => array(
+                'condition' => $bAuthorIcon,
+                'content' => array(
+                    'author_icon' => $sAuthorIcon
+                )
+            ),
+            'bx_if:show_author_icon_empty' => array(
+                'condition' => !$bAuthorIcon,
+                'content' => array()
+            ),
+            'author_url' => $sAuthorUrl,
+            'author_title' => bx_html_attribute($sAuthorName),
+            'author_name' => $sAuthorName,
+            'bx_if:show_icon' => array (
+                'condition' => $sIconUrl,
+                'content' => array(
+                	'icon_url' => $sIconUrl,
+                ),
+            ),
+            'bx_if:show_icon_empty' => array (
+                'condition' => !$sIconUrl,
+                'content' => array(
+                    'icon' => $CNF['ICON']
+                ),
+            ),
+            'bx_if:show_cover' => array (
+                'condition' => $sCoverUrl,
+                'content' => array (
+                    'summary_attr' => bx_html_attribute($sSummaryPlain),
+                    'content_url' => $sUrl,
+                    'cover_url' => $sCoverUrl,
+                    'strecher' => str_repeat('&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ', 40),
+                ),
+            ),
+            'bx_if:show_cover_empty' => array (
+                'condition' => !$sCoverUrl,
+                'content' => array (
+                    'summary_plain' => $sSummaryPlain,
+                    'strecher' => mb_strlen($sSummaryPlain) > 240 ? '' : str_repeat('&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ', round((240 - mb_strlen($sSummaryPlain)) / 6)),
+                ),
+            ),
+            'content_url' => $sUrl,
+    		'votes' => $sVotes,
+            'date' => bx_time_js($aData[$CNF['FIELD_ADDED']]),
     		'bx_if:show_single' => array(
     			'condition' => $bTmplVarsSingle,
     			'content' => $aTmplVarsSingle

+ 4 - 0
modules/boonex/market/install/config.php

@@ -65,6 +65,10 @@ $aConfig = array(
      * Transcoders.
      */
     'transcoders' => array(
+        'bx_market_icon',
+        'bx_market_thumb',
+        'bx_market_cover',
+        'bx_market_screenshot',
 		'bx_market_preview',
         'bx_market_gallery',
     ),

+ 7 - 0
modules/boonex/market/install/langs/en.xml

@@ -174,6 +174,9 @@
 
     <string name="_bx_market_menu_set_title_view_entry"><![CDATA[Product Actions]]></string>
     <string name="_bx_market_menu_title_view_entry"><![CDATA[Product Actions]]></string>
+    
+    <string name="_bx_market_menu_title_view_entry_popup"><![CDATA[Product Actions in popup)]]></string>
+    
     <string name="_bx_market_menu_title_submenu"><![CDATA[Market Submenu]]></string>
     <string name="_bx_market_menu_set_title_submenu"><![CDATA[Market Submenu]]></string>
     <string name="_bx_market_menu_item_title_system_create_entry"><![CDATA[New Product]]></string>
@@ -223,6 +226,10 @@
 	<string name="_bx_market_menu_item_title_system_notifications_licenses"><![CDATA[Licenses]]></string>
 	<string name="_bx_market_menu_item_title_notifications_licenses"><![CDATA[Licenses]]></string>
 
+	<string name="_bx_market_menu_title_snippet"><![CDATA[Snippet Actions]]></string>
+    <string name="_bx_market_menu_set_title_snippet"><![CDATA[Snippet Actions]]></string>
+    <string name="_bx_market_menu_item_title_system_snippet_more"><![CDATA[More Actions]]></string>
+    <string name="_bx_market_menu_item_title_snippet_more"><![CDATA[More Actions]]></string>
 
 	<string name="_bx_market_grid_filter_item_title_adm_select_one_filter1"><![CDATA[All Statuses]]></string>
 	<string name="_bx_market_grid_filter_item_title_adm_active"><![CDATA[Active]]></string>

+ 1 - 1
modules/boonex/market/install/sql/disable.sql

@@ -13,7 +13,7 @@ DELETE FROM `sys_pages_blocks` WHERE `module` = 'bx_market' OR `object` IN('bx_m
 -- MENU
 DELETE FROM `sys_objects_menu` WHERE `module` = 'bx_market';
 DELETE FROM `sys_menu_sets` WHERE `module` = 'bx_market';
-DELETE FROM `sys_menu_items` WHERE `module` = 'bx_market' OR `set_name` IN('bx_market_view', 'bx_market_submenu', 'bx_market_view_submenu', 'bx_market_my');
+DELETE FROM `sys_menu_items` WHERE `module` = 'bx_market' OR `set_name` IN('bx_market_view', 'bx_market_submenu', 'bx_market_view_submenu', 'bx_market_my', 'bx_market_snippet');
 
 -- PRIVACY 
 DELETE FROM `sys_objects_privacy` WHERE `object` IN ('bx_market_allow_view_to', 'bx_market_allow_purchase_to', 'bx_market_allow_comment_to', 'bx_market_allow_vote_to');

+ 12 - 1
modules/boonex/market/install/sql/enable.sql

@@ -191,7 +191,8 @@ INSERT INTO `sys_menu_items` (`set_name`, `module`, `name`, `title_system`, `tit
 
 -- MENU: actions menu for view entry 
 INSERT INTO `sys_objects_menu`(`object`, `title`, `set_name`, `module`, `template_id`, `deletable`, `active`, `override_class_name`, `override_class_file`) VALUES 
-('bx_market_view', '_bx_market_menu_title_view_entry', 'bx_market_view', 'bx_market', 9, 0, 1, 'BxMarketMenuView', 'modules/boonex/market/classes/BxMarketMenuView.php');
+('bx_market_view', '_bx_market_menu_title_view_entry', 'bx_market_view', 'bx_market', 9, 0, 1, 'BxMarketMenuView', 'modules/boonex/market/classes/BxMarketMenuView.php'),
+('bx_market_view_popup', '_bx_market_menu_title_view_entry_popup', 'bx_market_view', 'bx_market', 4, 0, 1, 'BxMarketMenuView', 'modules/boonex/market/classes/BxMarketMenuView.php');
 
 INSERT INTO `sys_menu_sets`(`set_name`, `module`, `title`, `deletable`) VALUES 
 ('bx_market_view', 'bx_market', '_bx_market_menu_set_title_view_entry', 0);
@@ -214,6 +215,16 @@ 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_market_my', 'bx_market', 'create-product', '_bx_market_menu_item_title_system_create_entry', '_bx_market_menu_item_title_create_entry', 'page.php?i=create-product', '', '', 'plus', '', 2147483647, 1, 0, 0);
 
+-- MENU: actions menu for snippet
+INSERT INTO `sys_objects_menu`(`object`, `title`, `set_name`, `module`, `template_id`, `deletable`, `active`, `override_class_name`, `override_class_file`) VALUES 
+('bx_market_snippet', '_bx_market_menu_title_snippet', 'bx_market_snippet', 'bx_market', 10, 0, 1, 'BxMarketMenuSnippetActions', 'modules/boonex/market/classes/BxMarketMenuSnippetActions.php');
+
+INSERT INTO `sys_menu_sets`(`set_name`, `module`, `title`, `deletable`) VALUES 
+('bx_market_snippet', 'bx_market', '_bx_market_menu_set_title_snippet', 0);
+
+INSERT INTO `sys_menu_items`(`set_name`, `module`, `name`, `title_system`, `title`, `link`, `onclick`, `target`, `icon`, `addon`, `submenu_object`, `submenu_popup`, `visible_for_levels`, `active`, `copyable`, `editable`, `order`) VALUES 
+('bx_market_snippet', 'bx_market', 'snippet-more', '_bx_market_menu_item_title_system_snippet_more', '_bx_market_menu_item_title_snippet_more', 'javascript:void(0)', 'bx_menu_popup(''bx_market_view_popup'', this, {''id'':''bx_market_snippet_{content_id}''}, {id:{content_id}});', '', 'chevron-down', '', 'bx_market_view_popup', 1, 2147483647, 1, 0, 0, 1);
+
 
 -- MENU: module sub-menu
 INSERT INTO `sys_objects_menu`(`object`, `title`, `set_name`, `module`, `template_id`, `deletable`, `active`, `override_class_name`, `override_class_file`) VALUES 

+ 4 - 0
modules/boonex/market/install/sql/install.sql

@@ -254,6 +254,8 @@ INSERT INTO `sys_objects_storage` (`object`, `engine`, `params`, `token_life`, `
 
 INSERT INTO `sys_objects_transcoder` (`object`, `storage_object`, `source_type`, `source_params`, `private`, `atime_tracking`, `atime_pruning`, `ts`) VALUES 
 ('bx_market_preview', 'bx_market_photos_resized', 'Storage', 'a:1:{s:6:"object";s:16:"bx_market_photos";}', 'no', '1', '2592000', '0'),
+('bx_market_icon', 'bx_market_photos_resized', 'Storage', 'a:1:{s:6:"object";s:16:"bx_market_photos";}', 'no', '1', '2592000', '0'),
+('bx_market_thumb', 'bx_market_photos_resized', 'Storage', 'a:1:{s:6:"object";s:16:"bx_market_photos";}', 'no', '1', '2592000', '0'),
 ('bx_market_cover', 'bx_market_photos_resized', 'Storage', 'a:1:{s:6:"object";s:16:"bx_market_photos";}', 'no', '1', '2592000', '0'),
 ('bx_market_screenshot', 'bx_market_photos_resized', 'Storage', 'a:1:{s:6:"object";s:16:"bx_market_photos";}', 'no', '1', '2592000', '0'),
 ('bx_market_gallery', 'bx_market_photos_resized', 'Storage', 'a:1:{s:6:"object";s:16:"bx_market_photos";}', 'no', '1', '2592000', '0');
@@ -261,6 +263,8 @@ INSERT INTO `sys_objects_transcoder` (`object`, `storage_object`, `source_type`,
 INSERT INTO `sys_transcoder_filters` (`transcoder_object`, `filter`, `filter_params`, `order`) VALUES 
 ('bx_market_preview', 'Resize', 'a:3:{s:1:"w";s:3:"300";s:1:"h";s:3:"200";s:11:"crop_resize";s:1:"1";}', '0'),
 ('bx_market_gallery', 'Resize', 'a:1:{s:1:"w";s:3:"500";}', '0'),
+('bx_market_icon', 'Resize', 'a:3:{s:1:"w";s:2:"50";s:1:"h";s:2:"50";s:13:"square_resize";s:1:"1";}', '0'),
+('bx_market_thumb', 'Resize', 'a:3:{s:1:"w";s:3:"100";s:1:"h";s:3:"100";s:13:"square_resize";s:1:"1";}', '0'),
 ('bx_market_cover', 'Resize', 'a:1:{s:1:"w";s:4:"2000";}', '0'),
 ('bx_market_screenshot', 'Resize', 'a:3:{s:1:"w";s:3:"200";s:1:"h";s:3:"120";s:11:"crop_resize";s:1:"1";}', '0');
 

+ 50 - 2
modules/boonex/market/template/css/main.css

@@ -7,10 +7,58 @@ div.bx-market-unit-gallery-cnt {
 	width: 100%;
 	overflow: hidden;
 }
-div.bx-market-unit-title {
+div.bx-market-unit-info {
+	position: relative;
+}
+
+/*+++ Item Author +++*/
+div.bx-market-unit-author {
+    position: relative;
+	text-align: left;
+}
+div.bx-market-unit-author-avatar {
+    position: absolute;
+    top: 0px;
+    left: 0px;
+}
+div.bx-market-unit-author {
+    white-space: nowrap;
+}
+div.bx-market-unit-author-name,
+div.bx-market-unit-author div.bx-market-unit-info {
+    text-overflow: ellipsis;
+    overflow: hidden;
+}
+
+/*+++ Item Actions +++*/
+div.bx-market-unit-actions {
+	position: absolute;
+	top: 0px;
+	right: 0px;	
+}
+
+/*+++ Item Info +++*/
+div.bx-market-unit-cnt {
+	text-align: left;
+}
+div.bx-market-unit-icon {
+    position: absolute;
+    top: 0px;
+    left: 0px;
+}
+div.bx-market-unit-icon-empty {
+	background-color: #ffffff;
 	text-align: center;
+	font-size: 32px;
+	font-size: 2rem;
 }
-div.bx-market-unit-info {
+div.bx-market-unit-icon-empty .sys-icon {
+    vertical-align: top;	
+}
+div.bx-market-unit-cover {
+	background-color: #ffffff;
+}
+div.bx-market-unit-cnt div.bx-market-unit-info {
 	overflow: visible;
 	white-space: nowrap;
 }

+ 58 - 25
modules/boonex/market/template/unit_gallery.html

@@ -1,35 +1,68 @@
 <div class="bx-base-text-unit bx-base-text-unit-gallery bx-def-gal-unit-size bx-def-padding-sec">
-	<div class="bx-market-unit-gallery-cnt bx-def-round-corners bx-def-box bx-def-color-bg-box">
-	    <bx_if:thumb>
-	        <a href="__content_url__" title="__summary_attr__">
-	            <div class="bx-base-text-unit-thumb bx-def-gal-div-size bx-def-font-middle" style="background-image:url(__gallery_url__)">
-	                <div class="bx-base-text-unit-strecher">__strecher__</div>
-	            </div>
-	        </a>
-	    </bx_if:thumb>
-	    <bx_if:no_thumb>
-	        <div class="bx-def-gal-img-column">
-	            <div class="bx-base-text-unit-no-thumb bx-def-gal-div-size bx-def-font-middle bx-def-font-grayed bx-def-padding bx-def-box-sizing">
-	                __summary_plain__
-	                <div class="bx-base-text-unit-strecher">__strecher__</div>
-	            </div>
-	        </div>
-	    </bx_if:no_thumb>
-		<div class="bx-market-unit-cnt bx-def-padding-sec">
-		    <div class="bx-market-unit-title bx-def-gal-unit-column">
-				<a class="bx-def-margin-sec-topbottom bx-def-font-color" href="__content_url__">__title__</a>
+	<div class="bx-market-unit-gallery-cnt bx-def-round-corners bx-def-box bx-def-color-bg-box bx-def-shadow">
+        <div class="bx-market-unit-cnt bx-def-padding">
+            <div class="bx-market-unit-author">
+		        <div class="bx-market-unit-author-avatar bx-def-thumb bx-def-thumb-size">
+		            <bx_if:show_author_icon>
+		                <img class="bx-def-thumb bx-def-thumb-size" src="__author_icon__" />
+		            </bx_if:show_author_icon>
+		            <bx_if:show_author_icon_empty>
+		                <i class="sys-icon user"></i>
+		            </bx_if:show_author_icon_empty>
+		        </div>
+		        <div class="bx-market-unit-author-info bx-def-thumb-size-min-height bx-def-thumb-size-left-indent">
+		            <div class="bx-market-unit-author-name bx-def-padding-thd-top">
+		                <a href="__author_url__" class="bx-market-unit-author-name" title="__author_title__">__author_name__</a>
+		            </div>
+		            <div class="bx-market-unit-info bx-def-font-small">
+		                <span class="bx-market-unit-date bx-def-font-grayed">__date__</span>
+		            </div>
+		        </div>
+		        <div class="bx-market-unit-actions">__actions__</div>
+            </div>
+        </div>
+        <div class="bx-market-unit-cnt bx-market-unit-cover">
+		    <bx_if:show_cover>
+	            <a href="__content_url__" title="__summary_attr__">
+	                <div class="bx-base-text-unit-thumb bx-def-gal-div-size bx-def-font-middle" style="background-image:url(__cover_url__)">
+	                    <div class="bx-base-text-unit-strecher">__strecher__</div>
+	                </div>
+	            </a>
+	        </bx_if:show_cover>
+	        <bx_if:show_cover_empty>
+                <div class="bx-base-text-unit-no-thumb bx-def-gal-div-size bx-def-font-middle bx-def-font-grayed bx-def-padding bx-def-box-sizing">
+                    __summary_plain__
+                    <div class="bx-base-text-unit-strecher">__strecher__</div>
+                </div>
+	        </bx_if:show_cover_empty>
+        </div>
+		<div class="bx-market-unit-cnt bx-def-padding">
+            <div class="bx-market-unit-info">
+                <div class="bx-market-unit-icon bx-def-thumb-size bx-def-round-corners">
+                    <a href="__content_url__"> 
+		                <bx_if:show_icon>
+		                    <img class="bx-market-unit-icon bx-def-thumb-size bx-def-round-corners" src="__icon_url__" />
+		                </bx_if:show_icon>
+		                <bx_if:show_icon_empty>
+		                    <div class="bx-market-unit-icon-empty bx-def-thumb-size bx-def-round-corners">
+                                <i class="sys-icon __icon__"></i>
+                            </div>
+		                </bx_if:show_icon_empty>
+		            </a>
+                </div>
+			    <div class="bx-market-unit-title bx-def-thumb-size-min-height bx-def-thumb-size-left-indent">
+					<a class="bx-def-margin-sec-topbottom bx-def-font-color" href="__content_url__">__title__</a>
+			    </div>
 		    </div>
-
-		    <div class="bx-market-unit-info bx-base-text-unit-info bx-def-margin-thd-top">
-		    	<div class="bx-market-ui-cell bx-market-uic-left">__entry_votes__</div>
+		    <div class="bx-market-unit-info bx-base-text-unit-info bx-def-margin-sec-top">
+		    	<div class="bx-market-ui-cell bx-market-uic-left">__votes__</div>
 		        <div class="bx-market-ui-cell bx-market-uic-right">
-		        	<!-- TODO: Buttons to checkout instead of text price. -->
 		        	<bx_if:show_single>
-			        	<a class="bx-market-ui-price bx-btn bx-btn-small" href="javascript:void(0)" onclick="javascript:__entry_price_single_onclick__">__entry_price_single__</a>
+			        	<a class="bx-market-ui-price bx-btn bx-btn-small" href="javascript:void(0)" onclick="javascript:__price_single_onclick__">__price_single__</a>
 					</bx_if:show_single>
 		        	<bx_if:show_recurring>
 		        		<span class="bx-market-ui-price-or bx-def-font-grayed"><bx_text:_bx_market_txt_or /></span>
-		        		<a class="bx-market-ui-price bx-btn bx-btn-small" href="javascript:void(0)" onclick="javascript:__entry_price_recurring_onclick__">__entry_price_recurring__</a>
+		        		<a class="bx-market-ui-price bx-btn bx-btn-small" href="javascript:void(0)" onclick="javascript:__price_recurring_onclick__">__price_recurring__</a>
 		        	</bx_if:show_recurring>
 		        	<bx_if:show_free>
 		        		<span class="bx-market-ui-price bx-def-font-semibold col-green3"><bx_text:_bx_market_txt_get_for_free /></span>