Forráskód Böngészése

Ticket #5316 - Paid Levels: Create the block with the available actions of the mem level.

AntonLV 10 hónapja
szülő
commit
787a183663

+ 17 - 9
inc/classes/BxDolAclQuery.php

@@ -145,13 +145,12 @@ class BxDolAclQuery extends BxDolDb implements iBxDolSingleton
         $sSelectClause = $sJoinClause = $sWhereClause = $sGroupClause = $sOrderClause = $sLimitClause = "";
 
         if(!isset($aParams['order']) || empty($aParams['order']))
-           $sOrderClause = "ORDER BY `taa`.`Title` ASC";
+            $sOrderClause = "`taa`.`Title` ASC";
 
-           
         switch($aParams['type']) {
             case 'by_names_and_module':
-            	$aMethod['params'][1] = array(
-                	'module' => $aParams['module']
+                $aMethod['params'][1] = array(
+                    'module' => $aParams['module']
                 );
 
                 $sWhereClause .= " AND `taa`.`Name` IN(" . $this->implode_escape($aParams['value']) . ") AND `taa`.`Module` = :module ";
@@ -163,21 +162,24 @@ class BxDolAclQuery extends BxDolDb implements iBxDolSingleton
                 break;
 
             case 'by_level_id':
-            	$aMethod['params'][1] = array(
-                	'level_id' => $aParams['value'],
-                	'level_code' => pow(2, ($aParams['value'] - 1))
-                );
+                $aMethod['params'][1] = [
+                    'level_id' => $aParams['value'],
+                    'level_code' => pow(2, ($aParams['value'] - 1))
+                ];
 
                 $sSelectClause .= ", `tam`.`AllowedCount` AS `allowed_count`, `tam`.`AllowedPeriodLen` AS `allowed_period_len`, `tam`.`AllowedPeriodStart` AS `allowed_period_start`, `tam`.`AllowedPeriodEnd` AS `allowed_period_end`, `tam`.`AdditionalParamValue` AS `additional_param_value` ";
                 $sJoinClause .= "LEFT JOIN `sys_acl_matrix` AS `tam` ON `taa`.`ID`=`tam`.`IDAction` ";
                 $sWhereClause .= "AND `tam`.`IDLevel`=:level_id AND (`taa`.`DisabledForLevels`='0' OR `taa`.`DisabledForLevels`&:level_code=0)";
+
+                if(isset($aParams['start'], $aParams['limit']))
+                    $sLimitClause = $this->prepareAsString("?, ?", $aParams['start'], $aParams['limit']);
                 break;
 
             case 'by_level_id_key_id':
                 $aMethod['name'] = 'getAllWithKey';
                 $aMethod['params'][1] = 'id';
                 $aMethod['params'][2] = array(
-                	'level_id' => $aParams['value']
+                    'level_id' => $aParams['value']
                 );
 
                 $sSelectClause .= ", `tam`.`AllowedCount` AS `allowed_count`, `tam`.`AllowedPeriodLen` AS `allowed_period_len` ";
@@ -203,6 +205,12 @@ class BxDolAclQuery extends BxDolDb implements iBxDolSingleton
                 break;
         }
 
+        if($sOrderClause)
+            $sOrderClause = "ORDER BY " . $sOrderClause;
+
+        if($sLimitClause)
+            $sLimitClause = "LIMIT " . $sLimitClause;
+
         $aMethod['params'][0] = "SELECT " . ($bReturnCount ? "SQL_CALC_FOUND_ROWS" : "") . "
                 `taa`.`ID` AS `id`,
                 `taa`.`Module` AS `module`,

+ 6 - 2
modules/boonex/acl/classes/BxAclConfig.php

@@ -48,6 +48,8 @@ class BxAclConfig extends BxBaseModGeneralConfig
             'PARAM_RECURRING_RESERVE' => 'bx_acl_recurring_reserve',
             'PARAM_RECURRING_PRIORITIZE' => 'bx_acl_recurring_prioritize',
             'PARAM_SHOW_TO_UNAUTHENTICATED' => 'bx_acl_show_to_unauthenticated',
+            'PARAM_ACTIONS_LIMIT_BLOCK' => 20,
+            'PARAM_ACTIONS_LIMIT_POPUP' => 10,
 
             // objects 
             'OBJECT_GRID_ADMINISTRATION' => 'bx_acl_administration',
@@ -83,9 +85,11 @@ class BxAclConfig extends BxBaseModGeneralConfig
         );
 
         $sHtmlPrefix = str_replace('_', '-', $this->_sName);
-        $this->_aHtmlIds = array(
+        $this->_aHtmlIds = [
+            'actions_popup' => $sHtmlPrefix . '-actions-popup-',
+            'actions_list' => $sHtmlPrefix . '-actions-list-',
             'popup_price' => $sHtmlPrefix . '-popup-price'
-        );
+        ];
 
         $this->_iOwner = 0;
         $this->_aCurrency = [];

+ 9 - 0
modules/boonex/acl/classes/BxAclGridView.php

@@ -126,6 +126,15 @@ class BxAclGridView extends BxAclGridLevels
     	return parent::_getCellDefault($mixedValue, $sKey, $aField, $aRow);
     }
 
+    protected function _getCellLevelName($mixedValue, $sKey, $aField, $aRow)
+    {
+        $mixedValue = $this->_oModule->_oTemplate->parseLink('javascript:void(0)', $mixedValue, [
+            'onclick' => $this->_oModule->_oConfig->getJsObject('main') . '.viewActions(this, ' . $aRow['level_id'] . ')'
+        ]);
+
+    	return parent::_getCellDefault($mixedValue, $sKey, $aField, $aRow);
+    }
+
     protected function _getActionChoose ($sType, $sKey, $a, $isSmall = false, $isDisabled = false, $aRow = array())
     {
         if((float)$aRow['price'] != 0 || BxDolAcl::getInstance()->isMemberLevelInSet(array($aRow['level_id'])))

+ 42 - 1
modules/boonex/acl/classes/BxAclModule.php

@@ -51,6 +51,32 @@ class BxAclModule extends BxBaseModGeneralModule
     	));
     }
 
+    public function actionGetActionsInPopup($iLevelId)
+    {
+        return echoJson([
+            'code' => 0,
+            'popup' => [
+                'html' => $this->_oTemplate->displayActionsPopup($iLevelId), 
+                'options' => ['closeOnOuterClick' => true, 'removeOnClose' => true]
+            ],
+        ]);
+    }
+
+    public function actionGetActions($iLevelId)
+    {
+        if(($iGetStart = bx_get('start')) !== false)
+            $iStart = (int)$iGetStart;
+        if(($iGetPerPage = bx_get('per_page')) !== false)
+            $iLimit = (int)$iGetPerPage;
+        
+        return echoJson([
+            'code' => 0,
+            'level_id' => $iLevelId,
+            'content' => $this->_oTemplate->displayActions($iLevelId, $iStart, $iLimit),
+            'eval' => $this->_oConfig->getJsObject('main').'.onGetActions(oData)'
+        ]);
+    }
+
     /**
      * SERVICE METHODS
      */
@@ -121,8 +147,23 @@ class BxAclModule extends BxBaseModGeneralModule
             ];
 
         $this->_oTemplate->addCss(['view.css']);
+        $this->_oTemplate->addJs(['main.js']);
         return [
-            'content' => $oGrid->getCode()
+            'content' => $this->_oTemplate->getJsCode('main') . $oGrid->getCode()
+        ];
+    }
+
+    public function serviceGetBlockActions($iLevelId, $iStart = 0, $iLimit = 0)
+    {
+        if(($iGetStart = bx_get('start')) !== false)
+            $iStart = (int)$iGetStart;
+        if(($iGetPerPage = bx_get('per_page')) !== false)
+            $iLimit = (int)$iGetPerPage;
+
+        $mixedResult = $this->_oTemplate->displayActionsBlock($iLevelId, $iStart, $iLimit);
+
+        return !$this->_bIsApi ? $mixedResult : [
+            bx_api_get_block('acl_level_actions', $mixedResult)
         ];
     }
 

+ 104 - 8
modules/boonex/acl/classes/BxAclTemplate.php

@@ -15,17 +15,115 @@ class BxAclTemplate extends BxBaseModGeneralTemplate
     {
         parent::__construct($oConfig, $oDb);
     }
+    
+    public function displayActionsBlock($iLevelId, $iStart = 0, $iLimit = 0)
+    {
+        $aLevel = [];
+        BxDolAclQuery::getInstance()->getLevels(['type' => 'by_id', 'value' => $iLevelId], $aLevel, false);
+        if(empty($aLevel) || !is_array($aLevel))
+            return $this->_bIsApi ? [] : '';
+
+        $mixedResult = $this->displayActions($iLevelId, $iStart, $iLimit);
+        if($this->_bIsApi)
+            return $mixedResult;
+
+        $this->addCss(['main.css']);
+        $this->addJs(['main.js']);
+        return $this->parseHtmlByName('actions_block.html', [
+            'level' => _t('_bx_acl_txt_x_actions', _t($aLevel['name'])),
+            'actions' => $mixedResult,
+            'js_code' => $this->getJsCode('main')
+        ]);
+    }
+
+    public function displayActionsPopup($iLevelId)
+    {
+        $CNF = &$this->_oConfig->CNF;
 
-	public function displayEmptyOwner()
+        return BxTemplFunctions::getInstance()->transBox($this->_oConfig->getHtmlIds('actions_popup') . $iLevelId, $this->parseHtmlByName('actions_popup.html', [
+            'actions' => $this->displayActions($iLevelId, 0, $CNF['PARAM_ACTIONS_LIMIT_POPUP'])
+        ]));
+    }
+
+    public function displayActions($iLevelId, $iStart = 0, $iLimit = 0)
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+        if(!$iLimit)
+            $iLimit = !$this->_bIsApi ? $CNF['PARAM_ACTIONS_LIMIT_BLOCK'] : 9999;       
+
+        $aActions = [];
+        BxDolAclQuery::getInstance()->getActions(['type' => 'by_level_id', 'value' => $iLevelId, 'start' => $iStart, 'limit' => $iLimit + 1], $aActions, false);
+        if(empty($aActions) || !is_array($aActions))
+            return $this->_bIsApi ? [] : '';
+
+        $sTxtNo = _t('_No');
+
+        $aTmplVarsActions = [];
+        foreach($aActions as $aAction) {
+            $sTxtLimitCount = $sTxtNo;
+            if((bool)$aAction['countable'] && ($iCount = (int)$aAction['allowed_count']) > 0) {
+                if(($iPeriod = (int)$aAction['allowed_period_len']) > 0)
+                    $sTxtLimitCount = _t('_bx_acl_txt_n_times_m_hours', $iCount, $iPeriod);
+                else
+                    $sTxtLimitCount = _t('_bx_acl_txt_n_times', $iCount);
+            }
+
+            $sTxtLimitTime = $sTxtNo;
+            $bAfter = ($sK = 'allowed_period_start') && $aAction[$sK] && ($iAfter = strtotime($aAction[$sK])) != 0;
+            $bUntil = ($sK = 'allowed_period_end') && $aAction[$sK] && ($iUntil = strtotime($aAction[$sK])) != 0;
+            if($bAfter || $bUntil) {
+                $sAfter = $bAfter ? bx_time_js($iAfter, BX_FORMAT_DATE_TIME, true) : '';
+                $sUntil = $bUntil ? bx_time_js($iUntil, BX_FORMAT_DATE_TIME, true) : '';
+
+                if($bAfter && $bUntil)
+                    $sTxtLimitTime = _t('_bx_acl_txt_after_x_until_y', $sAfter, $sUntil);
+                else if($bAfter)
+                    $sTxtLimitTime = _t('_bx_acl_txt_after_x', $sAfter);
+                else if($bUntil)
+                    $sTxtLimitTime = _t('_bx_acl_txt_until_x', $sUntil);
+            }
+
+            $aTmplVarsActions[] = [
+                'action' => _t($aAction['title']),
+                'limit_count' => $sTxtLimitCount,
+                'limit_time' => $sTxtLimitTime
+            ];
+        }
+
+        if($this->_bIsApi)
+            return $aTmplVarsActions;
+
+        $oPaginate = new BxTemplPaginate([
+            'start' => $iStart,
+            'per_page' => $iLimit,
+            'on_change_page' => $this->_oConfig->getJsObject('main') . ".getActions(this, " . $iLevelId . ", {start}, {per_page})"
+        ]);
+        $oPaginate->setNumFromDataArray($aTmplVarsActions);
+        $sPaginate = $oPaginate->getSimplePaginate();
+
+        return $this->parseHtmlByName('actions_list.html', [
+            'html_id_actions' => $this->_oConfig->getHtmlIds('actions_list') . $iLevelId,
+            'bx_repeat:actions' => $aTmplVarsActions,
+            'bx_if:show_paginate' => [
+                'condition' => !empty($sPaginate),
+                'content' => [
+                    'paginate' => $sPaginate
+                ]
+            ]
+        ]);
+    }
+
+    public function displayEmptyOwner()
     {
     	return MsgBox(_t('_bx_acl_msg_empty_owner'));
     }
 
     public function displayMembershipActions($iProfileId)
     {
-		$this->addCss(array('pm_actions.css'));
+        $this->addCss(array('pm_actions.css'));
     	return $this->parseHtmlByName('pm_actions.html', array(
-    		'url_upgrade' => BX_DOL_URL_ROOT . BxDolPermalinks::getInstance()->permalink($this->_oConfig->CNF['URL_VIEW'])
+            'url_upgrade' => BX_DOL_URL_ROOT . BxDolPermalinks::getInstance()->permalink($this->_oConfig->CNF['URL_VIEW'])
     	));
     }
 
@@ -60,13 +158,11 @@ class BxAclTemplate extends BxBaseModGeneralTemplate
     	));
     }
 
-	public function getJsCode($sType, $aParams = array(), $bWrap = true)
+    public function getJsCode($sType, $aParams = [], $bWrap = true)
     {
-        $aParams = array_merge(array(
+        return parent::getJsCode($sType, array_merge([
             'aHtmlIds' => $this->_oConfig->getHtmlIds()
-        ), $aParams);
-
-        return parent::getJsCode($sType, $aParams, $bWrap);
+        ], $aParams), $bWrap);
     }
 }
 

+ 9 - 0
modules/boonex/acl/install/langs/en.xml

@@ -127,4 +127,13 @@
     <string name="_bx_acl_txt_none"><![CDATA[none]]></string>
     <string name="_bx_acl_txt_free"><![CDATA[free]]></string>
     <string name="_bx_acl_txt_lifetime"><![CDATA[lifetime]]></string>
+    <string name="_bx_acl_txt_x_actions"><![CDATA['{0}' Membership Level Actions]]></string>
+    <string name="_bx_acl_txt_action_title"><![CDATA[Action]]></string>
+    <string name="_bx_acl_txt_action_limit_count"><![CDATA[Limited in quantity]]></string>
+    <string name="_bx_acl_txt_action_limit_time"><![CDATA[Limited in time]]></string>
+    <string name="_bx_acl_txt_n_times"><![CDATA[{0} times]]></string>
+    <string name="_bx_acl_txt_n_times_m_hours"><![CDATA[{0} times resetting every {1} hours]]></string>
+    <string name="_bx_acl_txt_after_x"><![CDATA[allowed after {0}]]></string>
+    <string name="_bx_acl_txt_until_x"><![CDATA[allowed until {0}]]></string>
+    <string name="_bx_acl_txt_after_x_until_y"><![CDATA[allowed between {0} and {1}]]></string>
 </resources>

+ 67 - 9
modules/boonex/acl/js/main.js

@@ -9,27 +9,85 @@
  */
 
 function BxAclMain(oOptions) {
-	this._sActionsUri = oOptions.sActionUri;
+    this._sActionsUri = oOptions.sActionUri;
     this._sActionsUrl = oOptions.sActionUrl;
     this._sObjName = oOptions.sObjName == undefined ? 'oAclMain' : oOptions.sObjName;
     this._aHtmlIds = oOptions.aHtmlIds == undefined ? {} : oOptions.aHtmlIds;
     this._oRequestParams = oOptions.oRequestParams == undefined ? {} : oOptions.oRequestParams;
 }
 
+BxAclMain.prototype.viewActions = function(oElement, iLevelId) {
+    var $this = this;
+    var oData = this._getDefaultData();
+
+    if(oElement)
+        this.loadingInBlock(oElement, true);
+
+    jQuery.get(
+        this._sActionsUrl + 'get_actions_in_popup/' + iLevelId + '/',
+        oData,
+        function(oData) {
+            if(oElement)
+                $this.loadingInBlock(oElement, false);
+
+            processJsonData(oData);
+        },
+        'json'
+    );
+};
+
+BxAclMain.prototype.getActions = function(oElement, iLevelId, iStart, iPerPage) {
+    var $this = this;
+    var oData = this._getData({
+        start: iStart,
+        per_page: iPerPage
+    });
+
+    if(oElement)
+        this.loadingInList(oElement, true);
+
+    jQuery.get(
+        this._sActionsUrl + 'get_actions/' + iLevelId + '/',
+        oData,
+        function(oData) {
+            if(oElement)
+                $this.loadingInList(oElement, false);
+
+            processJsonData(oData);
+        },
+        'json'
+    );
+};
+
+BxAclMain.prototype.onGetActions = function(oData)
+{
+    if(oData && oData.level_id != undefined && oData.content != undefined)
+        $('#' + this._aHtmlIds['actions_list'] + oData.level_id).replaceWith(oData.content);
+};
+
+BxAclMain.prototype.loadingInBlock = function(e, bShow) {
+    var oParent = $(e).length ? $(e).parents('.bx-db-container:first') : $('body'); 
+    bx_loading(oParent, bShow);
+};
+
+BxAclMain.prototype.loadingInList = function(e, bShow) {
+    var oParent = $(e).length ? $(e).parents('.bx-acl-actions:first') : $('body'); 
+    bx_loading(oParent, bShow);
+};
+
 BxAclMain.prototype.loadingInButton = function(e, bShow) {
-	if($(e).length)
-		bx_loading_btn($(e), bShow);
-	else
-		bx_loading($('body'), bShow);	
+    if($(e).length)
+        bx_loading_btn($(e), bShow);
+    else
+        bx_loading($('body'), bShow);	
 };
 
-BxAclMain.prototype._loading = function(e, bShow) {
-	var oParent = $(e).length ? $(e) : $('body'); 
-	bx_loading(oParent, bShow);
+BxAclMain.prototype._getData = function (aData) {
+    return jQuery.extend({}, this._getDefaultData(), aData);
 };
 
 BxAclMain.prototype._getDefaultData = function () {
-	var oDate = new Date();
+    var oDate = new Date();
     return jQuery.extend({}, this._oRequestParams, {_t:oDate.getTime()});
 };
 

+ 5 - 0
modules/boonex/acl/template/actions_block.html

@@ -0,0 +1,5 @@
+<div class="bx-acl-title mb-4 flex items-center">
+    <div class="text-xl font-bold">__level__</div>
+</div>
+__actions__
+__js_code__

+ 19 - 0
modules/boonex/acl/template/actions_list.html

@@ -0,0 +1,19 @@
+<div id="__html_id_actions__" class="bx-acl-actions">
+    <div class="bx-acl-a-items">
+        <div class="bx-acl-a-item flex items-center w-full mt-2 first:mt-0 font-semibold">
+            <div class="bx-acl-ai-action flex-1"><bx_text:_bx_acl_txt_action_title /></div>
+            <div class="bx-acl-ai-points-active w-1/3 text-center"><bx_text:_bx_acl_txt_action_limit_count /></div>
+            <div class="bx-acl-ai-points-active w-1/3 text-center"><bx_text:_bx_acl_txt_action_limit_time /></div>
+        </div>
+        <bx_repeat:actions>
+            <div class="bx-acl-a-item flex items-center w-full mt-2 first:mt-0">
+                <div class="bx-acl-ai-action flex-1">__action__</div>
+                <div class="bx-acl-ai-limit-count w-1/3 text-xs text-center">__limit_count__</div>
+                <div class="bx-acl-ai-limit-time w-1/3 text-xs text-center">__limit_time__</div>
+            </div>
+        </bx_repeat:actions>
+    </div>
+    <div class="bx-acl-a-paginate mt-4 flex justify-end items-center">
+        <bx_if:show_paginate>__paginate__</bx_if:show_paginate>
+    </div>
+</div>

+ 3 - 0
modules/boonex/acl/template/actions_popup.html

@@ -0,0 +1,3 @@
+<div class="bx-acl-actions-popup bx-popup-width">
+    <div class="bx-acl-actions-popup-cnt p-4">__actions__</div>
+</div>

+ 9 - 0
modules/boonex/russian/data/langs/bx_acl/ru.xml

@@ -127,4 +127,13 @@
     <string name="_bx_acl_txt_none"><![CDATA[нет]]></string>
     <string name="_bx_acl_txt_free"><![CDATA[бесплатно]]></string>
     <string name="_bx_acl_txt_lifetime"><![CDATA[пожизненно]]></string>
+    <string name="_bx_acl_txt_x_actions"><![CDATA[Действия на уровне членства '{0}']]></string>
+    <string name="_bx_acl_txt_action_title"><![CDATA[Действие]]></string>
+    <string name="_bx_acl_txt_action_limit_count"><![CDATA[Ограничено в количестве]]></string>
+    <string name="_bx_acl_txt_action_limit_time"><![CDATA[Ограничено по времени]]></string>
+    <string name="_bx_acl_txt_n_times"><![CDATA[{0} раз]]></string>
+    <string name="_bx_acl_txt_n_times_m_hours"><![CDATA[{0} раз, сброс каждые {1} часов]]></string>
+    <string name="_bx_acl_txt_after_x"><![CDATA[разрешено после {0}]]></string>
+    <string name="_bx_acl_txt_until_x"><![CDATA[разрешено до {0}]]></string>
+    <string name="_bx_acl_txt_after_x_until_y"><![CDATA[разрешено между {0} и {1}]]></string>
 </resources>