AntonLV 6 лет назад
Родитель
Сommit
64400382b9

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

@@ -28,8 +28,14 @@ class BxAclConfig extends BxBaseModGeneralConfig
         parent::__construct($aModule);
 
         $this->CNF = array (
+            // database tables
             'TABLE_PRICES' => $aModule['db_prefix'] . 'level_prices',
 
+            // database fields
+            'FIELD_ID' => 'id',
+            'FIELD_LEVEL_ID' => 'level_id',
+            'FIELD_NAME' => 'name',
+
             // page URIs
             'URL_ADMINISTRATION' => 'page.php?i=acl-administration',
             'URL_VIEW' => 'page.php?i=acl-view',
@@ -58,26 +64,28 @@ class BxAclConfig extends BxBaseModGeneralConfig
 
         $this->_aJsClasses = array(
             'main' => 'BxAclMain',
+            'form' => 'BxAclForm',
             'administration' => 'BxAclAdministration',
         );
         $this->_aJsObjects = array(
             'main' => 'oAclMain',
+            'form' => 'oAclForm',
             'administration' => 'oAclAdministration',
         );
 
         $sHtmlPrefix = str_replace('_', '-', $this->_sName);
         $this->_aHtmlIds = array(
-        	'popup_price' => $sHtmlPrefix . '-popup-price'
+            'popup_price' => $sHtmlPrefix . '-popup-price'
         );
 
-		$oPayments = BxDolPayments::getInstance();
-		$this->_iOwner = (int)$oPayments->getOption('site_admin');
+        $oPayments = BxDolPayments::getInstance();
+        $this->_iOwner = (int)$oPayments->getOption('site_admin');
         $this->_aCurrency = array(
-        	'code' => $oPayments->getOption('default_currency_code'),
-        	'sign' => $oPayments->getOption('default_currency_sign')
+            'code' => $oPayments->getOption('default_currency_code'),
+            'sign' => $oPayments->getOption('default_currency_sign')
         );
 
-		$this->_bExpireNotifyOnce = true;
+        $this->_bExpireNotifyOnce = true;
         $this->_iExpireNotificationDays = 1;
         $this->_iRemoveExpiredFor = 30;
     }
@@ -125,6 +133,11 @@ class BxAclConfig extends BxBaseModGeneralConfig
     {
     	return $this->_aCurrency;
     }
+
+    public function getPriceName($sName)
+    {
+        return uriGenerate($sName, $this->CNF['TABLE_PRICES'], $this->CNF['FIELD_NAME']);
+    }
 }
 
 /** @} */

+ 135 - 0
modules/boonex/acl/classes/BxAclFormPrice.php

@@ -0,0 +1,135 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    PaidLevels Paid Levels
+ * @ingroup     UnaModules
+ * 
+ * @{
+ */
+
+class BxAclFormPrice extends BxTemplFormView
+{
+    protected $_sModule;
+    protected $_oModule;
+
+    public function __construct($aInfo, $oTemplate = false)
+    {
+        $this->_sModule = 'bx_acl';
+        $this->_oModule = BxDolModule::getInstance($this->_sModule);
+
+        parent::__construct($aInfo, $oTemplate);
+
+        $CNF = &$this->_oModule->_oConfig->CNF;
+
+        if(isset($this->aInputs[$CNF['FIELD_NAME']])) {
+            $sJsObject = $this->_oModule->_oConfig->getJsObject('form');
+
+            $iId = $this->getId();
+            $aMask = array('mask' => "javascript:%s.checkName('%s');", $sJsObject, $CNF['FIELD_NAME']);
+            if(!empty($iId) && $this->aParams['display'] == $CNF['OBJECT_FORM_PRICE_DISPLAY_EDIT']) {
+                $aMask['mask'] = "javascript:%s.checkName('%s', %d);";
+                $aMask[] = $iId;
+            }
+
+            $sOnBlur = call_user_func_array('sprintf', array_values($aMask)); 
+            $this->aInputs[$CNF['FIELD_NAME']]['attrs']['onblur'] = $sOnBlur;
+        }
+    }
+
+    public function setAction($sAction)
+    {
+        $this->aFormAttrs['action'] = $sAction;
+    }
+
+    public function setLevelId($iLevelId)
+    {
+        $CNF = &$this->_oModule->_oConfig->CNF;
+
+        $this->aInputs[$CNF['FIELD_LEVEL_ID']]['value'] = $iLevelId;
+        if(!empty($iLevelId) && empty($this->aInputs[$CNF['FIELD_NAME']]['value'])) {
+            $aLevel = $this->_oModule->_oDb->getLevels(array('type' => 'by_id', 'value' => $iLevelId));
+            $this->aInputs[$CNF['FIELD_NAME']]['value'] = $this->_oModule->_oConfig->getPriceName(_t($aLevel['name']));
+        }
+    }
+
+    public function getCode($bDynamicMode = false)
+    {
+    	$sJs = $this->_oModule->_oTemplate->addJs(array('form.js'), $bDynamicMode);
+
+        $sCode = '';
+        if($bDynamicMode)
+            $sCode .= $sJs;
+
+        $sCode .= $this->_oModule->_oTemplate->getJsCode('form');
+        $sCode .= parent::getCode($bDynamicMode);
+
+        return $sCode;
+    }
+
+    /*
+    public function initChecker ($aValues = array (), $aSpecificValues = array())
+    {
+        $CNF = &$this->_oModule->_oConfig->CNF;
+        
+        $bValues = $aValues && !empty($aValues[$CNF['FIELD_ID']]);
+
+        if(isset($this->aInputs[$CNF['FIELD_NAME']])) {
+            if ($bValues)
+                $this->aInputs[$CNF['FIELD_POLL']]['content_id'] = $aValues['id'];
+        }
+        
+        parent::initChecker ($aValues, $aSpecificValues);
+    }
+*/
+    
+    public function insert ($aValsToAdd = array(), $isIgnore = false)
+    {
+        $CNF = &$this->_oModule->_oConfig->CNF;
+
+        if(isset($this->aInputs[$CNF['FIELD_NAME']])) {
+            $sName = BxDolForm::getSubmittedValue($CNF['FIELD_NAME'], $this->aFormAttrs['method'], $this->_aSpecificValues);
+            $sName = $this->_oModule->_oConfig->getPriceName($sName);
+            BxDolForm::setSubmittedValue($CNF['FIELD_NAME'], $sName, $this->aFormAttrs['method'], $this->_aSpecificValues);
+        }
+
+        return parent::insert ($aValsToAdd, $isIgnore);
+    }
+
+    function update ($iContentId, $aValsToAdd = array(), &$aTrackTextFieldsChanges = null)
+    {
+        $CNF = &$this->_oModule->_oConfig->CNF;
+
+        $sNameKey = $CNF['FIELD_NAME'];
+        if(isset($this->aInputs[$sNameKey])) {
+            $sName = $this->getCleanValue($sNameKey);
+            $aContentInfo = $this->_oModule->_oDb->getPrices(array('type' => 'by_id', 'value' => $iContentId));
+
+            if($aContentInfo[$sNameKey] != $sName) {
+                $sName = $this->_oModule->_oConfig->getPriceName($sName);
+                BxDolForm::setSubmittedValue($sNameKey, $sName, $this->aFormAttrs['method'], $this->_aSpecificValues);
+            }
+        }
+
+        return parent::update ($iContentId, $aValsToAdd, $aTrackTextFieldsChanges);
+    }
+
+    public function getId()
+    {
+        $iResult = 0;
+
+        $aIds = bx_get('ids');
+        if(!$aIds || !is_array($aIds)) {
+            $sId = bx_get('id');
+            if(!empty($sId))
+                $iResult = $sId;
+        }
+        else
+            $iResult = array_shift($aIds);
+
+        return (int)$iResult;
+    }
+}
+
+/** @} */

+ 47 - 50
modules/boonex/acl/classes/BxAclGridAdministration.php

@@ -13,8 +13,8 @@ require_once('BxAclGridLevels.php');
 
 class BxAclGridAdministration extends BxAclGridLevels
 {
-	protected $_sParamsDivider = '#-#';
-	protected $_iLevelId = 0;
+    protected $_sParamsDivider = '#-#';
+    protected $_iLevelId = 0;
 
     public function __construct ($aOptions, $oTemplate = false)
     {
@@ -27,7 +27,7 @@ class BxAclGridAdministration extends BxAclGridLevels
         }
     }
 
-	public function performActionAdd()
+    public function performActionAdd()
     {
     	$CNF = &$this->_oModule->_oConfig->CNF;
 
@@ -41,26 +41,23 @@ class BxAclGridAdministration extends BxAclGridLevels
             $this->_iLevelId = (int)bx_get('level_id');
 
     	$oForm = BxDolForm::getObjectInstance($CNF['OBJECT_FORM_PRICE'], $CNF['OBJECT_FORM_PRICE_DISPLAY_ADD']);
-    	$oForm->aFormAttrs['action'] = BX_DOL_URL_ROOT . 'grid.php?o=' . $this->_sObject . '&a=' . $sAction . '&level=' . $this->_iLevelId;
-    	$oForm->aInputs['level_id']['value'] = $this->_iLevelId;
+        $oForm->setAction(BX_DOL_URL_ROOT . 'grid.php?o=' . $this->_sObject . '&a=' . $sAction . '&level=' . $this->_iLevelId);
+        $oForm->setLevelId($this->_iLevelId);
 
         $oForm->initChecker();
         if($oForm->isSubmittedAndValid()) {
-        	$iLevel = $oForm->getCleanValue('level_id');
-        	$iPeriod = $oForm->getCleanValue('period');
-        	$sPeriodUnit = $oForm->getCleanValue('period_unit');
+            $iLevel = $oForm->getCleanValue('level_id');
+            $iPeriod = $oForm->getCleanValue('period');
+            $sPeriodUnit = $oForm->getCleanValue('period_unit');
+
+            if(!empty($iPeriod) && empty($sPeriodUnit)) 
+                return echoJson(array('msg' => _t('_bx_acl_form_price_input_err_period_unit')));
 
-        	if(!empty($iPeriod) && empty($sPeriodUnit)) 
-        	    return echoJson(array('msg' => _t('_bx_acl_form_price_input_err_period_unit')));
-        	
             $aPrice = $this->_oModule->_oDb->getPrices(array('type' => 'by_level_id_duration', 'level_id' => $iLevel, 'period' => $iPeriod, 'period_unit' => $sPeriodUnit));
             if(!empty($aPrice) && is_array($aPrice))
                 return echoJson(array('msg' => _t('_bx_acl_err_price_duplicate')));
 
-            $aLevel = $this->_oModule->_oDb->getLevels(array('type' => 'by_id', 'value' => $iLevel));
-            $sName = uriGenerate(strtolower(_t($aLevel['name'])) . ' ' . $iPeriod . ' ' . $sPeriodUnit, $CNF['TABLE_PRICES'], 'name');
-
-            $iId = (int)$oForm->insert(array('name' => $sName, 'order' => $this->_oModule->_oDb->getPriceOrderMax($this->_iLevelId) + 1));
+            $iId = (int)$oForm->insert(array('order' => $this->_oModule->_oDb->getPriceOrderMax($this->_iLevelId) + 1));
             if($iId != 0) {
             	//TODO: May be we don't need to have this 'Purchasable' flag at all or at least we shouldn't update it from here.
                 $this->_oModule->_oDb->updateLevels(array('Purchasable' => 'yes'), array('ID' => $this->_iLevelId));
@@ -73,18 +70,18 @@ class BxAclGridAdministration extends BxAclGridLevels
             return;
         }
 
-		bx_import('BxTemplStudioFunctions');
-		$sContent = BxTemplStudioFunctions::getInstance()->popupBox($this->_oModule->_oConfig->getHtmlIds('popup_price'), _t('_bx_acl_popup_title_price_add'), $this->_oModule->_oTemplate->parseHtmlByName('popup_price.html', array(
-			'form_id' => $oForm->aFormAttrs['id'],
-			'form' => $oForm->getCode(true),
-			'object' => $this->_sObject,
-			'action' => $sAction
-		)));
+        bx_import('BxTemplStudioFunctions');
+        $sContent = BxTemplStudioFunctions::getInstance()->popupBox($this->_oModule->_oConfig->getHtmlIds('popup_price'), _t('_bx_acl_popup_title_price_add'), $this->_oModule->_oTemplate->parseHtmlByName('popup_price.html', array(
+            'form_id' => $oForm->aFormAttrs['id'],
+            'form' => $oForm->getCode(true),
+            'object' => $this->_sObject,
+            'action' => $sAction
+        )));
 
-		echoJson(array('popup' => array('html' => $sContent, 'options' => array('closeOnOuterClick' => false))));
+        echoJson(array('popup' => array('html' => $sContent, 'options' => array('closeOnOuterClick' => false, 'removeOnClose' => true))));
     }
 
-	public function performActionEdit()
+    public function performActionEdit()
     {
     	$CNF = &$this->_oModule->_oConfig->CNF;
 
@@ -98,12 +95,12 @@ class BxAclGridAdministration extends BxAclGridLevels
 
         $aItem = $this->_oModule->_oDb->getPrices(array('type' => 'by_id', 'value' => $iId));
         if(!is_array($aItem) || empty($aItem)) {
-        	echoJson(array());
-			exit;
+            echoJson(array());
+            exit;
         }
 
         $oForm = BxDolForm::getObjectInstance($CNF['OBJECT_FORM_PRICE'], $CNF['OBJECT_FORM_PRICE_DISPLAY_EDIT']);
-    	$oForm->aFormAttrs['action'] = BX_DOL_URL_ROOT . 'grid.php?o=' . $this->_sObject . '&a=' . $sAction . '&level=' . $this->_iLevelId;
+        $oForm->setAction(BX_DOL_URL_ROOT . 'grid.php?o=' . $this->_sObject . '&a=' . $sAction . '&level=' . $this->_iLevelId);
 
         $oForm->initChecker($aItem);
         if($oForm->isSubmittedAndValid()) {
@@ -116,24 +113,24 @@ class BxAclGridAdministration extends BxAclGridLevels
             return;
         }
 
-		bx_import('BxTemplStudioFunctions');
-		$sContent = BxTemplStudioFunctions::getInstance()->popupBox($this->_oModule->_oConfig->getHtmlIds('popup_price'), _t('_bx_acl_popup_title_price_edit'), $this->_oModule->_oTemplate->parseHtmlByName('popup_price.html', array(
-			'form_id' => $oForm->aFormAttrs['id'],
-			'form' => $oForm->getCode(true),
-			'object' => $this->_sObject,
-			'action' => $sAction
-		)));
+        bx_import('BxTemplStudioFunctions');
+        $sContent = BxTemplStudioFunctions::getInstance()->popupBox($this->_oModule->_oConfig->getHtmlIds('popup_price'), _t('_bx_acl_popup_title_price_edit'), $this->_oModule->_oTemplate->parseHtmlByName('popup_price.html', array(
+            'form_id' => $oForm->aFormAttrs['id'],
+            'form' => $oForm->getCode(true),
+            'object' => $this->_sObject,
+            'action' => $sAction
+        )));
 
-		$aRes = array('popup' => array('html' => $sContent, 'options' => array('closeOnOuterClick' => false)));
+        $aRes = array('popup' => array('html' => $sContent, 'options' => array('closeOnOuterClick' => false, 'removeOnClose' => true)));
 
-		echoJson($aRes);
+        echoJson($aRes);
     }
 
-	public function performActionDelete()
+    public function performActionDelete()
     {
-    	$CNF = &$this->_oModule->_oConfig->CNF;
+        $CNF = &$this->_oModule->_oConfig->CNF;
 
-    	$aIds = bx_get('ids');
+        $aIds = bx_get('ids');
         if(!$aIds || !is_array($aIds)) {
             echoJson(array());
             return;
@@ -142,12 +139,12 @@ class BxAclGridAdministration extends BxAclGridLevels
         $iAffected = 0;
         $aIdsAffected = array();
         foreach($aIds as $iId)
-			if($this->_oModule->_oDb->deletePrices(array('id' => $iId))) {
-				$aIdsAffected[] = $iId;
-        		$iAffected++;
-			}
+            if($this->_oModule->_oDb->deletePrices(array('id' => $iId))) {
+                $aIdsAffected[] = $iId;
+                $iAffected++;
+            }
 
-		echoJson($iAffected ? array('grid' => $this->getCode(false), 'blink' => $aIdsAffected) : array('msg' => _t('_bx_acl_err_cannot_perform')));
+        echoJson($iAffected ? array('grid' => $this->getCode(false), 'blink' => $aIdsAffected) : array('msg' => _t('_bx_acl_err_cannot_perform')));
     }
 
     protected function _addJsCss()
@@ -160,7 +157,7 @@ class BxAclGridAdministration extends BxAclGridLevels
         $oForm->addCssJs();
     }
 
-	protected function _getActionAdd ($sType, $sKey, $a, $isSmall = false, $isDisabled = false, $aRow = array())
+    protected function _getActionAdd ($sType, $sKey, $a, $isSmall = false, $isDisabled = false, $aRow = array())
     {
         if(empty($this->_iLevelId))
             $isDisabled = true;
@@ -168,7 +165,7 @@ class BxAclGridAdministration extends BxAclGridLevels
         return  parent::_getActionDefault($sType, $sKey, $a, false, $isDisabled, $aRow);
     }
 
-	protected function _getFilterControls()
+    protected function _getFilterControls()
     {
         parent::_getFilterControls();
 
@@ -188,7 +185,7 @@ class BxAclGridAdministration extends BxAclGridLevels
 
         $aLevels = $this->_oModule->_oDb->getLevels(array('type' => 'for_selector'));
         foreach($aLevels as $iId => $sTitle)
-        	$aInputLevels['values'][$iId] = _t($sTitle);
+            $aInputLevels['values'][$iId] = _t($sTitle);
 
         $sContent .=  $oForm->genRow($aInputLevels);
 
@@ -207,12 +204,12 @@ class BxAclGridAdministration extends BxAclGridLevels
         return $sContent;
     }
 
-	protected function _getDataSql($sFilter, $sOrderField, $sOrderDir, $iStart, $iPerPage)
+    protected function _getDataSql($sFilter, $sOrderField, $sOrderDir, $iStart, $iPerPage)
     {
         if(empty($this->_iLevelId) && strpos($sFilter, $this->_sParamsDivider) !== false)
             list($this->_iLevelId, $sFilter) = explode($this->_sParamsDivider, $sFilter);
 
-		if(empty($this->_iLevelId))
+        if(empty($this->_iLevelId))
             return array();
 
         $this->_aOptions['source'] .= $this->_oModule->_oDb->prepareAsString("AND `level_id`=? ", $this->_iLevelId);
@@ -220,7 +217,7 @@ class BxAclGridAdministration extends BxAclGridLevels
         return parent::_getDataSql($sFilter, $sOrderField, $sOrderDir, $iStart, $iPerPage);;
     }
 
-	protected function _isVisibleGrid ($a)
+    protected function _isVisibleGrid ($a)
     {
         return isAdmin();
     }

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

@@ -26,9 +26,30 @@ class BxAclModule extends BxDolModule
         $this->_oConfig->init($this->_oDb);
     }
 
-	/**
+    /**
      * ACTION METHODS
      */
+    public function actionCheckName()
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+    	$sName = bx_process_input(bx_get('name'));
+    	if(empty($sName))
+            return echoJson(array());
+
+        $sResult = '';
+
+        $iId = (int)bx_get('id');
+        if(!empty($iId)) {
+            $aPrice = $this->_oDb->getPrices(array('type' => 'by_id', 'value' => $iId)); 
+            if(strcmp($sName, $aPrice[$CNF['FIELD_NAME']]) == 0) 
+                $sResult = $sName;
+        }
+
+    	echoJson(array(
+            'name' => !empty($sResult) ? $sResult : $this->_oConfig->getPriceName($sName)
+    	));
+    }
 
     /**
      * SERVICE METHODS

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

@@ -24,6 +24,10 @@
 	<string name="_bx_acl_form_price_display_edit"><![CDATA[Edit]]></string>
 	<string name="_bx_acl_form_price_input_sys_id"><![CDATA[ID]]></string>
 	<string name="_bx_acl_form_price_input_sys_level_id"><![CDATA[Level ID]]></string>
+        <string name="_bx_acl_form_price_input_sys_name"><![CDATA[Name]]></string>
+	<string name="_bx_acl_form_price_input_name"><![CDATA[Name]]></string>
+	<string name="_bx_acl_form_price_input_inf_name"><![CDATA[Unique value which will be used in back end and API calls]]></string>
+        <string name="_bx_acl_form_price_input_err_name"><![CDATA[You need to enter a unique value here]]></string>
 	<string name="_bx_acl_form_price_input_sys_period"><![CDATA[Period]]></string>
 	<string name="_bx_acl_form_price_input_period"><![CDATA[Period]]></string>
 	<string name="_bx_acl_form_price_input_inf_period"><![CDATA[Use 0 for lifetime]]></string>

+ 18 - 15
modules/boonex/acl/install/sql/install.sql

@@ -19,7 +19,7 @@ CREATE TABLE `bx_acl_level_prices` (
 
 -- FORMS
 INSERT INTO `sys_objects_form` (`object`, `module`, `title`, `action`, `form_attrs`, `submit_name`, `table`, `key`, `uri`, `uri_title`, `params`, `deletable`, `active`, `override_class_name`, `override_class_file`) VALUES
-('bx_acl_price', @sName, '_bx_acl_form_price', '', '', 'do_submit', 'bx_acl_level_prices', 'id', '', '', '', 0, 1, '', '');
+('bx_acl_price', @sName, '_bx_acl_form_price', '', '', 'do_submit', 'bx_acl_level_prices', 'id', '', '', '', 0, 1, 'BxAclFormPrice', 'modules/boonex/acl/classes/BxAclFormPrice.php');
 
 INSERT INTO `sys_form_displays` (`display_name`, `module`, `object`, `title`, `view_mode`) VALUES
 ('bx_acl_price_add', @sName, 'bx_acl_price', '_bx_acl_form_price_display_add', 0),
@@ -28,6 +28,7 @@ INSERT INTO `sys_form_displays` (`display_name`, `module`, `object`, `title`, `v
 INSERT INTO `sys_form_inputs` (`object`, `module`, `name`, `value`, `values`, `checked`, `type`, `caption_system`, `caption`, `info`, `required`, `collapsed`, `html`, `attrs`, `attrs_tr`, `attrs_wrapper`, `checker_func`, `checker_params`, `checker_error`, `db_pass`, `db_params`, `editable`, `deletable`) VALUES
 ('bx_acl_price', @sName, 'id', '', '', 0, 'hidden', '_bx_acl_form_price_input_sys_id', '', '', 1, 0, 0, '', '', '', '', '', '', 'Int', '', 1, 0),
 ('bx_acl_price', @sName, 'level_id', '', '', 0, 'hidden', '_bx_acl_form_price_input_sys_level_id', '', '', 1, 0, 0, '', '', '', '', '', '', 'Int', '', 1, 0),
+('bx_acl_price', @sName, 'name', '', '', 0, 'text', '_bx_acl_form_price_input_sys_name', '_bx_acl_form_price_input_name', '_bx_acl_form_price_input_inf_name', 1, 0, 0, '', '', '', 'Avail', '', '_bx_acl_form_price_input_err_name', 'Xss', '', 1, 0),
 ('bx_acl_price', @sName, 'period', '', '', 0, 'text', '_bx_acl_form_price_input_sys_period', '_bx_acl_form_price_input_period', '_bx_acl_form_price_input_inf_period', 1, 0, 0, '', '', '', '', '', '', 'Int', '', 1, 0),
 ('bx_acl_price', @sName, 'period_unit', '', '#!bx_acl_period_units', 0, 'select', '_bx_acl_form_price_input_sys_period_unit', '_bx_acl_form_price_input_period_unit', '_bx_acl_form_price_input_inf_period_unit', 1, 0, 0, '', '', '', '', '', '', 'Xss', '', 1, 0),
 ('bx_acl_price', @sName, 'trial', '', '', 0, 'text', '_bx_acl_form_price_input_sys_trial', '_bx_acl_form_price_input_trial', '_bx_acl_form_price_input_inf_trial', 0, 0, 0, '', '', '', '', '', '', 'Int', '', 1, 0),
@@ -39,23 +40,25 @@ INSERT INTO `sys_form_inputs` (`object`, `module`, `name`, `value`, `values`, `c
 INSERT INTO `sys_form_display_inputs` (`display_name`, `input_name`, `visible_for_levels`, `active`, `order`) VALUES
 ('bx_acl_price_add', 'id', 2147483647, 0, 1),
 ('bx_acl_price_add', 'level_id', 2147483647, 1, 2),
-('bx_acl_price_add', 'price', 2147483647, 1, 3),
-('bx_acl_price_add', 'period', 2147483647, 1, 4),
-('bx_acl_price_add', 'period_unit', 2147483647, 1, 5),
-('bx_acl_price_add', 'trial', 2147483647, 1, 6),
-('bx_acl_price_add', 'controls', 2147483647, 1, 7),
-('bx_acl_price_add', 'do_submit', 2147483647, 1, 8),
-('bx_acl_price_add', 'do_cancel', 2147483647, 1, 9),
+('bx_acl_price_add', 'name', 2147483647, 1, 3),
+('bx_acl_price_add', 'price', 2147483647, 1, 4),
+('bx_acl_price_add', 'period', 2147483647, 1, 5),
+('bx_acl_price_add', 'period_unit', 2147483647, 1, 6),
+('bx_acl_price_add', 'trial', 2147483647, 1, 7),
+('bx_acl_price_add', 'controls', 2147483647, 1, 8),
+('bx_acl_price_add', 'do_submit', 2147483647, 1, 9),
+('bx_acl_price_add', 'do_cancel', 2147483647, 1, 10),
 
 ('bx_acl_price_edit', 'id', 2147483647, 1, 1),
 ('bx_acl_price_edit', 'level_id', 2147483647, 1, 2),
-('bx_acl_price_edit', 'price', 2147483647, 1, 3),
-('bx_acl_price_edit', 'period', 2147483647, 1, 4),
-('bx_acl_price_edit', 'period_unit', 2147483647, 1, 5),
-('bx_acl_price_edit', 'trial', 2147483647, 1, 6),
-('bx_acl_price_edit', 'controls', 2147483647, 1, 7),
-('bx_acl_price_edit', 'do_submit', 2147483647, 1, 8),
-('bx_acl_price_edit', 'do_cancel', 2147483647, 1, 9);
+('bx_acl_price_edit', 'name', 2147483647, 1, 3),
+('bx_acl_price_edit', 'price', 2147483647, 1, 4),
+('bx_acl_price_edit', 'period', 2147483647, 1, 5),
+('bx_acl_price_edit', 'period_unit', 2147483647, 1, 6),
+('bx_acl_price_edit', 'trial', 2147483647, 1, 7),
+('bx_acl_price_edit', 'controls', 2147483647, 1, 8),
+('bx_acl_price_edit', 'do_submit', 2147483647, 1, 9),
+('bx_acl_price_edit', 'do_cancel', 2147483647, 1, 10);
 
 
 -- PRE-VALUES

+ 48 - 0
modules/boonex/acl/js/form.js

@@ -0,0 +1,48 @@
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    PaidLevels Paid Levels
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+function BxAclForm(oOptions) {
+    this._sActionsUri = oOptions.sActionUri;
+    this._sActionsUrl = oOptions.sActionUrl;
+    this._sObjName = oOptions.sObjName == undefined ? 'oBxAclForm' : oOptions.sObjName;
+    this._iOwnerId = oOptions.iOwnerId == undefined ? 0 : oOptions.iOwnerId;
+    this._sAnimationEffect = oOptions.sAnimationEffect == undefined ? 'slide' : oOptions.sAnimationEffect;
+    this._iAnimationSpeed = oOptions.iAnimationSpeed == undefined ? 'slow' : oOptions.iAnimationSpeed;
+    this._aHtmlIds = oOptions.aHtmlIds == undefined ? {} : oOptions.aHtmlIds;
+    this._oRequestParams = oOptions.oRequestParams == undefined ? {} : oOptions.oRequestParams;
+}
+
+BxAclForm.prototype.checkName = function(sNameId, iId) {
+    var oDate = new Date();
+
+    var oName = jQuery("[name='" + sNameId + "']");
+    var sName = oName.val();
+
+    if(!sName.length)
+        return;
+
+    jQuery.get(
+        this._sActionsUrl + 'check_name',
+        {
+            name: sName,
+            id: iId && parseInt(iId) > 0 ? iId : 0,
+            _t: oDate.getTime()
+        },
+        function(oData) {
+            if(!oData || oData.name == undefined)
+                return;
+
+            oName.val(oData.name);
+        },
+        'json'
+    );
+};
+
+/** @} */

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

@@ -24,6 +24,10 @@
 	<string name="_bx_acl_form_price_display_edit"><![CDATA[Редактирование]]></string>
 	<string name="_bx_acl_form_price_input_sys_id"><![CDATA[ID]]></string>
 	<string name="_bx_acl_form_price_input_sys_level_id"><![CDATA[ID уровня]]></string>
+        <string name="_bx_acl_form_price_input_sys_name"><![CDATA[Имя]]></string>
+	<string name="_bx_acl_form_price_input_name"><![CDATA[Имя]]></string>
+	<string name="_bx_acl_form_price_input_inf_name"><![CDATA[Уникальное значение, которое будет использоваться в серверной части и API запросах]]></string>
+        <string name="_bx_acl_form_price_input_err_name"><![CDATA[Введите уникальное значение]]></string>
 	<string name="_bx_acl_form_price_input_sys_period"><![CDATA[Период]]></string>
 	<string name="_bx_acl_form_price_input_period"><![CDATA[Период]]></string>
 	<string name="_bx_acl_form_price_input_inf_period"><![CDATA[Используйте 0 для пожизненного]]></string>