%PDF- %PDF-
Direktori : /home/bitrix/www/bitrix/modules/currency/lib/integration/ |
Current File : //home/bitrix/www/bitrix/modules/currency/lib/integration/iblockmoneyproperty.php |
<? namespace Bitrix\Currency\Integration; use Bitrix\Main\Localization\Loc; use Bitrix\Currency\CurrencyTable; use Bitrix\Currency\Helpers\Editor; use Bitrix\Main\Type\RandomSequence; use Bitrix\Currency\CurrencyManager; use Bitrix\Main\Web\Json; Loc::loadMessages(__FILE__); class IblockMoneyProperty { const USER_TYPE = 'Money'; const SEPARATOR = '|'; /** * Returns property type description. * * @return array */ public static function getUserTypeDescription() { $className = get_called_class(); return array( 'PROPERTY_TYPE' => 'S', 'USER_TYPE' => self::USER_TYPE, 'DESCRIPTION' => Loc::getMessage('CIMP_INPUT_DESCRIPTION'), 'GetPublicEditHTML' => array($className, 'getPublicEditHTML'), 'GetPublicViewHTML' => array($className, 'getPublicViewHTML'), 'GetPropertyFieldHtml' => array($className, 'getPropertyFieldHtml'), 'GetAdminListViewHTML' => array($className, 'getAdminListViewHTML'), 'CheckFields' => array($className, 'checkFields'), 'GetLength' => array($className, 'getLength'), 'ConvertToDB' => array($className, 'convertToDB'), 'ConvertFromDB' => array($className, 'convertFromDB'), 'AddFilterFields' => array($className, 'addFilterFields'), ); } /** * Return html for public edit value. * * @param array $property Property data. * @param array $value Current value. * @param array $controlSettings Form data. * @return string */ public static function getPublicEditHTML($property, $value, $controlSettings) { return self::getPropertyFieldHtml($property, $value, $controlSettings); } /** * Return html for public view value. * * @param array $property Property data. * @param array $value Current value. * @param array $controlSettings Form data. * @return string */ public static function getPublicViewHTML($property, $value, $controlSettings) { return self::getAdminListViewHTML($property, $value, $controlSettings); } /** * The method should return the html display for editing property values in the administrative part. * * @param array $property Property data. * @param array $value Current value. * @param array $controlSettings Form data. * @return string */ public static function getPropertyFieldHtml($property, $value, $controlSettings) { $seed = (!empty($controlSettings['VALUE'])) ? $controlSettings['VALUE'] : 'IMPSeed'; $randomGenerator = new RandomSequence($seed); $randString = strtolower($randomGenerator->randString(6)); $explode = is_string($value['VALUE']) ? explode(self::SEPARATOR, $value['VALUE']) : array(); $currentValue = $explode[0] ? $explode[0] : ''; $currentCurrency = $explode[1] ? $explode[1] : ''; $html = '<input type="text" style="width: auto;" value="'.htmlspecialcharsbx($currentValue). '" id="input-'.$randString.'">'; $html .= '<input type="hidden" id="hidden-'.$randString.'" name="'. htmlspecialcharsbx($controlSettings['VALUE']).'" value="'.htmlspecialcharsbx($value["VALUE"]).'">'; $listCurrency = self::getListCurrency(); if($listCurrency) { if($property['MULTIPLE'] == 'Y') $html .= '<input type="hidden" data-id="'.$randString.'">'; $html .= '<select id="selector-'.$randString.'" style="width: auto; margin: 0 5px;">'; foreach($listCurrency as $currency) { $selected = ($currentCurrency == $currency['CURRENCY'] || (!$currentCurrency && $currency['BASE'] == 'Y')) ? 'selected' : ''; $html .= '<option '.$selected.' value="'.$currency['CURRENCY'].'">'. htmlspecialcharsbx($currency['NAME']).'</option>'; } $html .= '</select>'; $html .= '<span id="error-'.$randString.'" style="color: red;"></span>'; $html .= self::getJsHandlerSelector($randString, $listCurrency); } return $html; } /** * The method must return safe HTML display the value of the properties on the list of items the administrative part. * * @param array $property Property data. * @param array $value Current value. * @param array $controlSettings Form data. * @return mixed|string */ public static function getAdminListViewHTML($property, $value, $controlSettings) { $explode = is_string($value['VALUE']) ? explode(self::SEPARATOR, $value['VALUE']) : array(); $currentValue = $explode[0] ? $explode[0] : ''; $currentCurrency = $explode[1] ? $explode[1] : ''; if (!$currentCurrency) return intval($currentValue) ? $currentValue : ''; if (CurrencyManager::isCurrencyExist($currentCurrency)) { if(!empty($controlSettings['MODE'])) { switch($controlSettings['MODE']) { case 'CSV_EXPORT': return $value['VALUE']; case 'SIMPLE_TEXT': return $currentValue; case 'ELEMENT_TEMPLATE': return $currentValue; } } list($currentValue, $currentCurrency, $decimalsValue) = self::getSeparatedValues($value['VALUE']); $currentValue = $currentValue.'.'.$decimalsValue; return \CCurrencyLang::CurrencyFormat($currentValue, $currentCurrency, true); } return ''; } /** * Check fields before inserting into the database. * * @param array $property Property data. * @param array $value Current value. * @return array An empty array, if no errors. */ public static function checkFields($property, $value) { $result = array(); if(empty($value['VALUE'])) return $result; $explode = is_string($value['VALUE']) ? explode(self::SEPARATOR, $value['VALUE']) : array(); $currentValue = $explode[0] ? $explode[0] : ''; $currentCurrency = $explode[1] ? $explode[1] : ''; if(!$currentCurrency) return intval($currentValue) ? $result : array(Loc::getMessage('CIMP_FORMAT_ERROR')); if(CurrencyManager::isCurrencyExist($currentCurrency)) { $format = \CCurrencyLang::GetFormatDescription($currentCurrency); $decPoint = $format['DEC_POINT']; $thousandsSep = $format['THOUSANDS_SEP']; $decimals = $format['DECIMALS']; $regExp = '/^\d{1,3}(('.$thousandsSep.'){0,1}\d{3})*(\\'.$decPoint.'\d{1,'.$decimals.'})?$/'; if($thousandsSep && $decPoint) { if ($decimals > 0) { $regExp = '/^\d{1,3}(('.$thousandsSep.'){0,1}\d{3})*(\\'.$decPoint.'\d{1,'.$decimals.'})?$/'; } else { $regExp = '/^\d{1,3}(('.$thousandsSep.'){0,1}\d{3})?$/'; } } elseif($thousandsSep && !$decPoint) { $regExp = '/^\d{1,3}(('.$thousandsSep.'){0,1}\d{3})*$/'; } elseif(!$thousandsSep && $decPoint) { if ($decimals > 0) { $regExp = '/^[0-9]*(\\'.$decPoint.'\d{1,'.$decimals.'})?$/'; } else { $regExp = '/^[0-9]?$/'; } } elseif(!$thousandsSep && !$decPoint) { $regExp = '/^[0-9]*$/'; } if(!preg_match($regExp, $currentValue)) { $result[] = Loc::getMessage('CIMP_FORMAT_ERROR'); } } else { $result[] = Loc::getMessage('CIMP_FORMAT_ERROR'); } return $result; } /** * Get the length of the value. Checks completion of mandatory. * * @param array $property Property data. * @param array $value Current value. * @return int */ public static function getLength($property, $value) { return strlen(trim($value['VALUE'], "\n\r\t")); } /** * The method is to convert the value of a format suitable for storage in a database. * * @param array $property Property data. * @param array $value Current value. * @return mixed */ public static function convertToDB($property, $value) { return $value; } /** * The method is to convert the property value in the processing format. * * @param array $property Property data. * @param array $value Current value. * @return mixed */ public static function convertFromDB($property, $value) { return $value; } private static function getSeparatedValues($value) { $explode = is_string($value) ? explode(self::SEPARATOR, $value) : array(); $currentValue = $explode[0] ? $explode[0] : ''; $currentCurrency = $explode[1] ? $explode[1] : ''; $format = \CCurrencyLang::GetFormatDescription($currentCurrency); $explode = explode($format['DEC_POINT'], $currentValue); $currentValue = $explode[0] ? $explode[0] : ''; $decimalsValue = $explode[1] ? $explode[1] : ''; return array($currentValue, $currentCurrency, $decimalsValue); } /** * Add values in filter. * * @param array $property Property data. * @param array $controlSettings Form data. * @param array &$filter Filter data. * @param bool &$filtered Marker filter. * @return void */ public static function addFilterFields($property, $controlSettings, &$filter, &$filtered) { $filtered = false; if(isset($_REQUEST[$controlSettings['VALUE']])) { $value = $_REQUEST[$controlSettings['VALUE']]; } elseif(isset($controlSettings["FILTER_ID"])) { $filterOption = new \Bitrix\Main\UI\Filter\Options($controlSettings["FILTER_ID"]); $filterData = $filterOption->getFilter(); if(!empty($filterData[$controlSettings['VALUE']])) $value = $filterData[$controlSettings['VALUE']]; } if(!empty($value)) { $explode = explode(self::SEPARATOR, $value); if(empty($explode[1])) { $listCurrency = self::getListCurrency(); if($listCurrency) { $filter[$controlSettings['VALUE']] = array(); foreach($listCurrency as $currencyType => $currency) { $filter[$controlSettings['VALUE']][] = $value.self::SEPARATOR.$currencyType; } } } $filtered = true; } } protected static function getListCurrency() { $result = Editor::getListCurrency(); return (empty($result) ? array() : $result); } protected static function getJsHandlerSelector($randString, array $listCurrency) { ob_start(); ?> <script> if (!window.BX && top.BX) window.BX = top.BX; BX.ready(function() { 'use strict'; if(!BX.HandlerMoneyField) { BX.HandlerMoneyField = function(params) { this.randomString = params.randomString; this.listCurrency = params.listCurrency; this.defaultSeparator = params.defaultSeparator; setTimeout(BX.proxy(this.setDefaultParams, this), 300); }; BX.HandlerMoneyField.prototype.setDefaultParams = function() { this.input = BX('input-' + this.randomString); this.hidden = BX('hidden-' + this.randomString); this.selector = BX('selector-' + this.randomString); this.error = BX('error-' + this.randomString); this.init(); }; BX.HandlerMoneyField.prototype.init = function() { if (!this.input || !this.selector || !this.hidden) return; this.currentCurrency = this.selector.value; this.currentFormat = null; this.oldFormat = { 'currentCurrency': this.currentCurrency, 'decPoint': this.listCurrency[this.currentCurrency].DEC_POINT, 'thousandsSep': this.listCurrency[this.currentCurrency].SEPARATOR }; this.availableKey = [8,9,13,36,37,39,38,40,46,18,17,16,188,190,86,65,112,113,114,115,116,117,118, 119,120,121,122,123,67,45,34,33,35]; this.availableSymbol = []; this.changeCurrency(); BX.bind(this.selector, 'change', BX.proxy(this.changeCurrency, this)); BX.bind(this.input, 'keydown', BX.proxy(function(event) {this.onkeydown(event)}, this)); BX.bind(this.input, 'keyup', BX.proxy(this.onkeyup, this)); BX.bind(this.input, 'blur', BX.proxy(this.onblur, this)); BX.bind(this.input, 'focus', BX.proxy(this.onfocus, this)); BX.addCustomEvent(window, 'onAddNewRowBeforeInner', BX.proxy(function(htmlObject) { var regExp = new RegExp('data-id=".+?"', 'g'), oldId; var match = htmlObject.html.match(regExp); if(match) match = match[0].match(/"([^"]*)"/i); if(match) oldId = match[1]; if(this.randomString == oldId) { var newId = BX.util.getRandomString(6).toLowerCase(); htmlObject.html = htmlObject.html.replace(new RegExp(oldId, 'g'), newId); } }, this)); }; BX.HandlerMoneyField.prototype.changeCurrency = function() { this.currentCurrency = (BX.proxy_context && BX.proxy_context.value) ? BX.proxy_context.value : this.selector.value; this.currentFormat = this.listCurrency[this.currentCurrency].FORMAT; this.decPoint = this.listCurrency[this.currentCurrency].DEC_POINT; this.thousandsSep = this.listCurrency[this.currentCurrency].SEPARATOR; this.decimals = this.listCurrency[this.currentCurrency].DECIMALS; if(this.realValue) { var regExp = this.oldFormat.thousandsSep ? '\\'+this.oldFormat.thousandsSep : ''; this.realValue = this.realValue.replace(new RegExp(regExp, 'g'),''); this.input.value = this.oldFormat.decPoint ? this.realValue.replace(this.oldFormat.decPoint,this.decPoint) : this.realValue; } this.oldFormat = { 'currentCurrency': this.currentCurrency, 'decPoint': this.decPoint, 'thousandsSep': this.thousandsSep }; this.setRealValue(); this.setVisibleValue(true); this.setHiddenValue(); var decimals = ''; for(var i = 1; i <= this.decimals; i++) decimals += i; this.availableSymbol.push(this.thousandsSep); this.availableSymbol.push(this.decPoint); this.regExp = ''; this.isDecimalsNull = (!parseInt(this.decimals)); if(this.thousandsSep && this.decPoint) { if (this.isDecimalsNull) { this.regExp = '^\\d{1,3}('+this.thousandsSep+'?\\d{3})?$'; this.exampleValue = '6'+this.thousandsSep+'456'; } else { this.regExp = '^\\d{1,3}('+this.thousandsSep+ '?\\d{3})*(\\'+this.decPoint+'\\d{1,'+this.decimals+'})?$'; this.exampleValue = '6'+this.thousandsSep+'456'+this.decPoint+decimals; } } else if(this.thousandsSep && !this.decPoint) { this.regExp = '^\\d{1,3}('+this.thousandsSep+'?\\d{3})*$'; this.exampleValue = '6'+this.thousandsSep+'456'; } else if(!this.thousandsSep && this.decPoint) { if (this.isDecimalsNull) { this.regExp = '^[0-9]?$'; this.exampleValue = '6456'; } else { this.regExp = '^[0-9]*(\\'+this.decPoint+'\\d{1,'+this.decimals+'})?$'; this.exampleValue = '6456'+this.decPoint+decimals; } } else if(!this.thousandsSep && !this.decPoint) { this.regExp = '^[0-9]*$'; this.exampleValue = '6456'; } this.checkFormatValue(); }; BX.HandlerMoneyField.prototype.onkeydown = function(event) { this.setTextError(); if (!BX.util.in_array(event.key, this.availableSymbol) && !BX.util.in_array(event.keyCode,this.availableKey)) { if (isNaN(parseInt(event.key))) { this.setTextError(BX.message('CIMP_INPUT_FORMAT_ERROR') .replace('#example#', this.exampleValue)); return BX.PreventDefault(event); } } }; BX.HandlerMoneyField.prototype.onkeyup = function() { this.setRealValue(); this.setHiddenValue(); this.setVisibleValue(true); }; BX.HandlerMoneyField.prototype.onblur = function() { this.setRealValue(); this.setHiddenValue(); this.setVisibleValue(true); this.setTextError(); this.checkFormatValue(); }; BX.HandlerMoneyField.prototype.onfocus = function() { this.input.value = this.realValue; }; BX.HandlerMoneyField.prototype.getTemplateValue = function() { return this.currentFormat.replace(new RegExp('(^|[^&])#'), '$1' + this.realValue); }; BX.HandlerMoneyField.prototype.checkFormatValue = function() { if(!this.realValue) return; var regExp = new RegExp(this.regExp); if(!this.realValue.match(regExp)) { this.setTextError(BX.message('CIMP_INPUT_FORMAT_ERROR') .replace('#example#', this.exampleValue)); } else { this.setTextError(); } }; BX.HandlerMoneyField.prototype.setTextError = function(text) { this.error.innerHTML = text ? text : ''; }; BX.HandlerMoneyField.prototype.setRealValue = function() { this.realValue = this.getFormatValue(); }; BX.HandlerMoneyField.prototype.setVisibleValue = function(useTemplate) { this.input.value = this.input.value ? !useTemplate ? this.getTemplateValue() : this.getFormatValue(): ''; }; BX.HandlerMoneyField.prototype.setHiddenValue = function() { if (this.input.value) { var regExp = this.thousandsSep ? '\\'+this.thousandsSep : ''; this.hidden.value = this.realValue.replace(new RegExp(regExp, 'g'), '') + this.defaultSeparator + this.currentCurrency; } else { this.hidden.value = ''; } }; BX.HandlerMoneyField.prototype.getFormatValue = function() { var baseValue = this.input.value; var valueLength = baseValue.length; var formatValue = ""; var regExp; if(this.thousandsSep == ',' || this.thousandsSep == '.') regExp = new RegExp('['+this.decPoint+']'); else regExp = new RegExp('['+this.decPoint+',.]'); var decPointPosition = baseValue.match(regExp); decPointPosition = decPointPosition == null ? baseValue.length : decPointPosition.index; var countDigit = 0; for(var i = 0; i < baseValue.length; i++) { var symbolPosition = baseValue.length-1-i; var symbol = baseValue.charAt(symbolPosition); var isDigit = ('0123456789'.indexOf(symbol) >= 0); if(isDigit) countDigit++; if(symbolPosition == decPointPosition) countDigit = 0; if(symbolPosition >= decPointPosition) { if(this.decPoint == '.' && symbol == ',') symbol = this.decPoint; if(this.decPoint == ',' && symbol == '.') symbol = this.decPoint; if(isDigit || (symbolPosition == decPointPosition && symbol == this.decPoint)) formatValue = symbol + formatValue; else if(valueLength > symbolPosition) valueLength--; } if(symbolPosition < decPointPosition) { if(isDigit) formatValue = symbol+formatValue; else if(valueLength > symbolPosition) valueLength--; if(isDigit && countDigit % 3 == 0 && countDigit !== 0 && symbolPosition !== 0) { formatValue = this.thousandsSep + formatValue; if(valueLength >= symbolPosition) valueLength++; } } } if(this.decimals > 0) { decPointPosition = formatValue.match(new RegExp('['+this.decPoint+']')); decPointPosition = decPointPosition == null ? formatValue.length : decPointPosition.index; while(formatValue.length-1-decPointPosition > this.decimals) { if(valueLength >= formatValue.length-1) valueLength--; formatValue = formatValue.substr(0, formatValue.length - 1); } } return formatValue; }; } var handlerMoneyField = new BX.HandlerMoneyField({ randomString: '<?=$randString?>', defaultSeparator: '<?=self::SEPARATOR?>', listCurrency: <?=Json::encode($listCurrency)?> }); BX.message({ CIMP_INPUT_FORMAT_ERROR: '<?=GetMessageJS('CIMP_INPUT_FORMAT_ERROR')?>' }); }); </script> <? $script = ob_get_contents(); ob_end_clean(); return $script; } }