Browse Source

Ticket #4759 - Market: Improve Header Image and Icon functionality.

AntonLV 2 năm trước cách đây
mục cha
commit
e9801279f8

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

@@ -69,6 +69,7 @@ class BxMarketConfig extends BxBaseModTextConfig
             'FIELD_THUMB' => 'thumb',
             'FIELD_COVER_RAW' => 'cover_raw',
             'FIELD_COVER' => 'cover',
+            'FIELD_COVER_POSITION' => 'cover_data',
             'FIELD_FILE' => 'files',
             'FIELD_PACKAGE' => 'package',
             'FIELD_NOTES_PURCHASED' => 'notes_purchased',
@@ -109,6 +110,7 @@ class BxMarketConfig extends BxBaseModTextConfig
             // some params
             'PARAM_AUTO_APPROVE' => 'bx_market_enable_auto_approve',
             'PARAM_NO_PAYMENTS' => 'bx_market_enable_no_payments',
+            'PARAM_USE_ICON' => 'bx_market_enable_icon',
             'PARAM_CHARS_SUMMARY' => 'bx_market_summary_chars',
             'PARAM_CHARS_SUMMARY_PLAIN' => 'bx_market_plain_summary_chars',
             'PARAM_NUM_RSS' => 'bx_market_rss_num',
@@ -165,7 +167,7 @@ class BxMarketConfig extends BxBaseModTextConfig
             'OBJECT_GRID_COMMON' => 'bx_market_common',
             'OBJECT_GRID_LICENSES_ADMINISTRATION' => 'bx_market_licenses_administration',
             'OBJECT_GRID_LICENSES' => 'bx_market_licenses',
-            'OBJECT_UPLOADERS' => array('bx_market_simple', 'bx_market_html5'),
+            'OBJECT_UPLOADERS' => ['bx_market_html5'],
             'OBJECT_CONNECTION_SUBENTRIES' => 'bx_market_subentries',
             
             'BADGES_AVALIABLE' => true,

+ 18 - 0
modules/boonex/market/classes/BxMarketModule.php

@@ -36,6 +36,24 @@ class BxMarketModule extends BxBaseModTextModule
         ));
     }
 
+    public function actionUpdateImage($sFiledName, $iContentId, $sValue)
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+        $aData = $this->_oDb->getContentInfoById($iContentId);
+        if(empty($aData) || !is_array($aData))
+            return;
+
+        $mixedResult = parent::actionUpdateImage($sFiledName, $iContentId, $sValue);
+        if($mixedResult === false)
+            return;
+        
+        if(!empty($aData[$sFiledName]) && ($oStorage = BxDolStorage::getObjectInstance($CNF['OBJECT_STORAGE'])) !== false)
+            $oStorage->deleteFile($aData[$sFiledName]);
+
+        echo $mixedResult;
+    }
+
     public function actionPerform()
     {
         $CNF = &$this->_oConfig->CNF;

+ 88 - 30
modules/boonex/market/classes/BxMarketTemplate.php

@@ -45,7 +45,7 @@ class BxMarketTemplate extends BxBaseModTextTemplate
 
         $aVars = parent::getTmplVarsText($aData);
 
-        //--- Process Cover
+        //--- Process RAW Cover
         $bCoverRaw = !empty($CNF['FIELD_COVER_RAW']) && !empty($aData[$CNF['FIELD_COVER_RAW']]);
 
         $aVars['bx_if:show_image_raw'] = [
@@ -55,27 +55,66 @@ class BxMarketTemplate extends BxBaseModTextTemplate
             ]
         ];
 
-        $aVars['bx_if:show_image']['condition'] = !$bCoverRaw && $aVars['bx_if:show_image']['condition'];
+        //--- Process Cover
+        $bIsAllowEditCover = $oModule->checkAllowedEdit($aData) === CHECK_ACTION_RESULT_ALLOWED;
+        $bShowImage = $aVars['bx_if:show_image']['condition'];
+
+        $aVars['bx_if:show_entry_cover'] = [
+            'condition' => !$bCoverRaw && ($bShowImage || $bIsAllowEditCover),
+            'content' => array_merge([
+                'bx_if:show_image' => [
+                    'condition' => $bShowImage,
+                    'content' => [true]
+                ],
+                'bx_if:show_image_empty' => [
+                    'condition' => !$bShowImage,
+                    'content' => [true]
+                ]
+            ], $aVars['bx_if:show_image']['content'])
+        ];
+
+        //--- Process Icon (Thumb)
+        $bIsAllowEditIcon = $bIsAllowEditCover;
 
-        //--- Process Thumb
         $sIcon = '';
-        $mixedIcon = $oModule->getEntryImageData($aData, 'FIELD_THUMB', array('OBJECT_IMAGES_TRANSCODER_THUMB', 'OBJECT_IMAGES_TRANSCODER_GALLERY'));
-        if($mixedIcon !== false) {
-            if(!empty($mixedIcon['object']))
-                $o = BxDolStorage::getObjectInstance($mixedIcon['object']);
-            else if(!empty($mixedIcon['transcoder']))
-                $o = BxDolTranscoder::getObjectInstance($mixedIcon['transcoder']);
-
-            if($o)
-                $sIcon = $o->getFileUrlById($mixedIcon['id']);
+        $bIcon = getParam($CNF['PARAM_USE_ICON']) == 'on';
+        if($bIcon) {
+            $mixedIcon = $oModule->getEntryImageData($aData, 'FIELD_THUMB', ['OBJECT_IMAGES_TRANSCODER_THUMB', 'OBJECT_IMAGES_TRANSCODER_GALLERY']);
+            if($mixedIcon !== false) {
+                if(!empty($mixedIcon['object']))
+                    $o = BxDolStorage::getObjectInstance($mixedIcon['object']);
+                else if(!empty($mixedIcon['transcoder']))
+                    $o = BxDolTranscoder::getObjectInstance($mixedIcon['transcoder']);
+
+                if($o)
+                    $sIcon = $o->getFileUrlById($mixedIcon['id']);
+            }
         }
 
-        $aVars['bx_if:show_icon'] = array(
-            'condition' => !empty($sIcon),
-            'content' => array(
-                'entry_icon' => $sIcon
-            )
-        );
+        $sIconUniqId = genRndPwd(8, false);
+        $sIconTweak = '';
+        if($bIsAllowEditIcon)
+            $sIconTweak = $this->_prepareImage($aData, $sIconUniqId, $CNF['OBJECT_UPLOADERS'], $CNF['OBJECT_STORAGE'], $CNF['FIELD_THUMB'], false);
+
+        $aVars = array_merge($aVars, [
+            'bx_if:show_entry_icon' => [
+                'condition' => $bIcon,
+                'content' => [
+                    'bx_if:show_icon' => [
+                        'condition' => !empty($sIcon),
+                        'content' => [true]
+                    ],
+                    'bx_if:show_icon_empty' => [
+                        'condition' => empty($sIcon),
+                        'content' => [true]
+                    ],
+                    'unique_id' => $sIconUniqId,
+                    'entry_icon' => $sIcon,
+                    'icon' => $CNF['ICON'],
+                    'icon_tweak' => $sIconTweak
+                ]
+            ]
+        ]);
 
         //--- Process Screenshots
         $sScreenshots = $this->getScreenshots($aData);
@@ -210,24 +249,21 @@ class BxMarketTemplate extends BxBaseModTextTemplate
 
         //--- Icon Info
         $sIconUrl = '';
-        if(!empty($CNF['FIELD_THUMB']) && $aData[$CNF['FIELD_THUMB']]) {
+        $bIcon = getParam($CNF['PARAM_USE_ICON']) == 'on';
+        if($bIcon && !empty($CNF['FIELD_THUMB']) && $aData[$CNF['FIELD_THUMB']]) {
             $iThumb = (int)$aData[$CNF['FIELD_THUMB']];
 
             $oStorage = BxDolStorage::getObjectInstance($CNF['OBJECT_STORAGE']);
             $aThumb = $oStorage->getFile($iThumb);
 
-            if(strpos($aThumb['mime_type'], 'svg') !== false)
-                $sIconUrl = $oStorage->getFileUrlById($iThumb);
+            if(!empty($aThumb) && is_array($aThumb)) {
+                if(strpos($aThumb['mime_type'], 'svg') !== false)
+                    $sIconUrl = $oStorage->getFileUrlById($iThumb);
 
-            if(empty($sIconUrl)) {
-                $oImagesTranscoder = BxDolTranscoderImage::getObjectInstance($CNF['OBJECT_IMAGES_TRANSCODER_ICON']);
-                if($oImagesTranscoder)
+                if(empty($sIconUrl) && ($oImagesTranscoder = BxDolTranscoderImage::getObjectInstance($CNF['OBJECT_IMAGES_TRANSCODER_ICON'])) !== false)
                     $sIconUrl = $oImagesTranscoder->getFileUrl($iThumb);
-            }
 
-            if(empty($sIconUrl)) {
-                $oImagesTranscoder = BxDolTranscoderImage::getObjectInstance($CNF['OBJECT_IMAGES_TRANSCODER_THUMB']);
-                if($oImagesTranscoder)
+                if(empty($sIconUrl) && ($oImagesTranscoder = BxDolTranscoderImage::getObjectInstance($CNF['OBJECT_IMAGES_TRANSCODER_THUMB'])) !== false)
                     $sIconUrl = $oImagesTranscoder->getFileUrl($iThumb);
             }
         }
@@ -337,12 +373,14 @@ class BxMarketTemplate extends BxBaseModTextTemplate
             'bx_if:show_icon' => array (
                 'condition' => $sIconUrl,
                 'content' => array(
-                	'icon_url' => $sIconUrl,
+                    'content_url' => $sUrl,
+                    'icon_url' => $sIconUrl,
                 ),
             ),
             'bx_if:show_icon_empty' => array (
-                'condition' => !$sIconUrl,
+                'condition' => $bIcon && !$sIconUrl,
                 'content' => array(
+                    'content_url' => $sUrl,
                     'icon' => $CNF['ICON']
                 ),
             ),
@@ -458,10 +496,30 @@ class BxMarketTemplate extends BxBaseModTextTemplate
         return array($oTranscoder, $oTranscoderPreview);
     }
 
+    protected function _getHeaderImageParams()
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+        return array_merge(parent::_getHeaderImageParams(), [
+            'field' => isset($CNF['FIELD_COVER']) ? $CNF['FIELD_COVER'] : false,
+            'field_position' => isset($CNF['FIELD_COVER_POSITION']) ? $CNF['FIELD_COVER_POSITION'] : false,
+        ]);
+    }
+
     protected function _getHeaderImage($aData)
     {
         return $this->getModule()->getEntryImageData($aData, 'FIELD_COVER');
     }
+    
+    function _prepareImage($aData, $sUniqId, $sUploader, $sStorage, $sField, $bAllowTweak, $bAllowMultiple = false)
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+        if(in_array($sField, [$CNF['FIELD_THUMB'], $CNF['FIELD_COVER']]))
+            $bAllowMultiple = true;
+
+        return parent::_prepareImage($aData, $sUniqId, $sUploader, $sStorage, $sField, $bAllowTweak, $bAllowMultiple);
+    }
 }
 
 /** @} */

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

@@ -15,6 +15,8 @@
     <string name="_bx_market_option_rss_num"><![CDATA[Number of items in RSS feed]]></string>
     <string name="_bx_market_option_searchable_fields"><![CDATA[Searchable fields for keyword search]]></string>
     <string name="_bx_market_option_per_page_for_favorites_lists"><![CDATA[Number of favorite lists per page]]></string>
+    <string name="_bx_market_option_enable_icon"><![CDATA[Enable product icon]]></string>
+    
 
     <string name="_bx_market_form_entry"><![CDATA[Product]]></string>
     <string name="_bx_market_form_entry_display_add"><![CDATA[Add Product]]></string>

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

@@ -20,7 +20,8 @@ INSERT INTO `sys_options` (`name`, `value`, `category_id`, `caption`, `type`, `c
 ('bx_market_per_page_profile', '6', @iCategId, '_bx_market_option_per_page_profile', 'digit', '', '', '', 21),
 ('bx_market_per_page_browse_showcase', '32', @iCategId, '_sys_option_per_page_browse_showcase', 'digit', '', '', '', 23),
 ('bx_market_rss_num', '10', @iCategId, '_bx_market_option_rss_num', 'digit', '', '', '', 25),
-('bx_market_searchable_fields', 'title,text', @iCategId, '_bx_market_option_searchable_fields', 'list', '', '', 'a:2:{s:6:"module";s:9:"bx_market";s:6:"method";s:21:"get_searchable_fields";}', 30);
+('bx_market_searchable_fields', 'title,text', @iCategId, '_bx_market_option_searchable_fields', 'list', '', '', 'a:2:{s:6:"module";s:9:"bx_market";s:6:"method";s:21:"get_searchable_fields";}', 30),
+('bx_market_enable_icon', '', @iCategId, '_bx_market_option_enable_icon', 'checkbox', '', '', '', 40);
 
 -- PAGE: create entry
 INSERT INTO `sys_objects_page`(`object`, `title_system`, `title`, `module`, `layout_id`, `visible_for_levels`, `visible_for_levels_editable`, `uri`, `url`, `meta_description`, `meta_keywords`, `meta_robots`, `cache_lifetime`, `cache_editable`, `deletable`, `override_class_name`, `override_class_file`) VALUES 

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

@@ -8,6 +8,7 @@ CREATE TABLE IF NOT EXISTS `bx_market_products` (
   `added` int(11) NOT NULL default '0',
   `changed` int(11) NOT NULL default '0',
   `thumb` int(11) NOT NULL default '0',
+  `thumb_data` varchar(50) NOT NULL,
   `cover` int(11) NOT NULL default '0',
   `cover_raw` longtext NOT NULL,
   `package` int(11) NOT NULL default '0',

+ 22 - 2
modules/boonex/market/template/css/entry.css

@@ -1,7 +1,27 @@
 /*--- Entry Cover ---*/
 .bx-cover-wrapper .bx-cover .bx-cover-image img {
-	border-width: 0px;
-	background-position: center center;
+    border-width: 0px;
+    background-position: center center;
+}
+
+/*--- Entry Icon ---*/
+.bx-market-ect-icon .bx-image-edit-buttons {
+  display: flex;
+  width: 100%;
+  justify-content: center;
+  left: 0px;
+  top: auto;
+  bottom: -0.75rem;
+}
+.bx-market-ect-icon .bx-btn.bx-btn-small i, 
+.bx-market-ect-icon .bx-btn.bx-btn-small img, 
+.bx-market-ect-icon .bx-btn.bx-btn-small svg {
+    height: 0.5rem;
+    width: 0.5rem;
+    line-height: 0.5rem;
+}
+.bx-market-ect-icon .bx-btn.bx-btn-small i {
+    font-size: 0.5rem;
 }
 
 /*--- Entry Content ---*/

+ 16 - 7
modules/boonex/market/template/entry-text.html

@@ -3,16 +3,25 @@
     <bx_if:show_image_raw>
         <div class="bx-base-text-entity-image bx-def-margin-bottom bx-def-font-align-center">__image_raw__</div>
     </bx_if:show_image_raw>
-    <bx_if:show_image>
-        <div class="bx-base-text-entity-image bx-def-margin-bottom bx-def-font-align-center">
-            <img class="bx-def-border-radius-block" src="__entry_image__" />
+    <bx_if:show_entry_cover>
+        <div class="bx-base-text-entity-image mb-4 text-center __add_class__ relative flex justify-center items-center">
+            <img class="aspect-video object-cover bg-cover rounded bx-image-edit-source-__unique_id__ __img_class__" style="background-image:url(__entry_image__); __image_settings__<bx_if:show_image_empty> display:none;</bx_if:show_image_empty>"  src="<bx_icon_url:spacer.gif />"/>
+            <div class="w-full h-32 border border-gray-300 dark:border-gray-700 border-dashed bg-gray-50 dark:bg-gray-900/50 rounded bx-image-edit-placeholder-__unique_id__"<bx_if:show_image> style="display:none;"</bx_if:show_image>></div>
+            __image_tweak__
         </div>
-    </bx_if:show_image>
+        __additional_code__
+    </bx_if:show_entry_cover>
     <div class="bx-base-text-entity-content bx-market-entity-content bx-def-constraint-list bx-def-constraint-pre bx-def-constraint-object bx-def-constraint-iframe bx-def-constraint-img bx-def-vanilla-html">
         <div class="bx-market-ec-title flex">
-            <bx_if:show_icon>
-                <div class="bx-market-ect-icon flex-none mr-4 not-prose"><img class="bx-def-thumb-size bx-def-round-corners" src="__entry_icon__"/></div>
-            </bx_if:show_icon>
+            <bx_if:show_entry_icon>
+                <div class="bx-market-ect-icon bx-def-thumb-size relative flex-none mr-4 not-prose">
+                    <img class="bx-def-thumb-size bx-def-round-corners bx-image-edit-source-__unique_id__" <bx_if:show_icon_empty> style="display:none"</bx_if:show_icon_empty> src="__entry_icon__"/>
+                    <div class="bx-def-thumb-size bx-image-edit-placeholder-__unique_id__ flex justify-center items-center bg-gray-100 dark:bg-gray-700 rounded-md" <bx_if:show_icon> style="display:none"</bx_if:show_icon>>
+                        <i class="sys-icon __icon__"></i>
+                    </div>
+                    __icon_tweak__
+                </div>
+            </bx_if:show_entry_icon>
             <div class="bx-market-ect-title bx-base-text-title-bages flex-1">
                 <h1>__entry_title__</h1>
                 <div class="bx-base-bages-container absolute flex -translate-y-5/4">__badges__</div>

+ 13 - 11
modules/boonex/market/template/unit.html

@@ -11,18 +11,20 @@
     </bx_if:show_cover>
     <div class="bx-base-text-unit-text p-3 md:p-4 lg:p-6 pt-2 md:pt-3 lg:pt-5 box-border">
         <div class="bx-market-unit-info flex items-center">
-            <div class="bx-market-unit-icon bx-def-thumb-size bx-def-round-corners">
-                <a href="__content_url__"> 
-                    <bx_if:show_icon>
+            <bx_if:show_icon>
+                <div class="bx-market-unit-icon bx-def-thumb-size bx-def-round-corners">
+                    <a href="__content_url__">
                         <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 flex justify-center items-center bg-gray-100 dark:bg-gray-700 rounded-md">
-                            <i class="sys-icon __icon__"></i>
-                        </div>
-                    </bx_if:show_icon_empty>
-                </a>
-            </div>
+                    </a>
+                </div>
+            </bx_if:show_icon>
+            <bx_if:show_icon_empty>
+                <div class="bx-market-unit-icon-empty bx-def-thumb-size flex justify-center items-center bg-gray-100 dark:bg-gray-700 rounded-md">
+                    <a href="__content_url__">
+                        <i class="sys-icon __icon__"></i>
+                    </a>
+                </div>
+            </bx_if:show_icon_empty>
             <div class="bx-market-unit-title ml-4 first:ml-0">
                 <div class="bx-base-text-unit-info flex space-x-1 text-sm text-gray-500 dark:text-gray-400">
                     <bx_if:meta><div class="bx-base-general-unit-meta">__meta__</div></bx_if:meta>

+ 12 - 10
modules/boonex/market/template/unit_gallery.html

@@ -36,18 +36,20 @@
         </div>
         <div class="bx-market-unit-cnt p-4">
             <div class="bx-market-unit-info flex items-center">
-                <div class="bx-market-unit-icon bx-def-thumb-size bx-def-round-corners">
-                    <a href="__content_url__"> 
-                        <bx_if:show_icon>
+                <bx_if:show_icon>
+                    <div class="bx-market-unit-icon bx-def-thumb-size bx-def-round-corners">
+                        <a href="__content_url__"> 
                             <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 flex justify-center items-center bg-gray-100 dark:bg-gray-700 rounded-md">
+                        </a>
+                    </div>
+                </bx_if:show_icon>
+                <bx_if:show_icon_empty>
+                    <div class="bx-market-unit-icon-empty bx-def-thumb-size flex justify-center items-center bg-gray-100 dark:bg-gray-700 rounded-md">
+                        <a href="__content_url__"> 
                             <i class="sys-icon __icon__"></i>
-                        </div>
-                        </bx_if:show_icon_empty>
-                    </a>
-                </div>
+                        </a> 
+                    </div>
+                </bx_if:show_icon_empty>
                 <div class="bx-market-unit-title ml-4 first:ml-0">
                     <div class="bx-market-unit-title-badges">
                         <a class=" bx-def-font-h3" href="__content_url__" title="__title_attr__">__title__</a> 

+ 1 - 0
modules/boonex/russian/data/langs/bx_market/ru.xml

@@ -15,6 +15,7 @@
     <string name="_bx_market_option_rss_num"><![CDATA[Количество элементов в ленте RSS]]></string>
     <string name="_bx_market_option_searchable_fields"><![CDATA[Поля для поиска по ключевому слову]]></string>
     <string name="_bx_market_option_per_page_for_favorites_lists"><![CDATA[Количество списков избранного на странице]]></string>
+    <string name="_bx_market_option_enable_icon"><![CDATA[Включить значок продукта]]></string>
 
     <string name="_bx_market_form_entry"><![CDATA[Продукт]]></string>
     <string name="_bx_market_form_entry_display_add"><![CDATA[Добавление продукта]]></string>