Новости | FAQ | Авторы | Документация | В действии | Библиотека |
Инструменты | Полезные ссылки | Хостинги | Скачать | Примеры | Форум |
Sumo 23.02.2015 17:36 / 23.02.2015 17:52
...проекта http://voda-uzao.ru@CLASS hydCore @USE pf/types/pfClass.p pf/tests/pfAssert.p pf/debug/pfRuntime.p hydBaseModel.p @BASE pfClass @auto[aFilespec] $[__^CLASS_NAME.upper[]_FILESPEC__][^aFilespec.match[^^(^taint[regex][$request:document-root])][][]] $[__^CLASS_NAME.upper[]_ABSOLUTE_FILESPEC__][$aFilespec] @create[aOptions] ^pfAssert:isTrue($aOptions.sql is pfSQL)[SQL-объект должен быть наследником pfSQL.] ^BASE:create[] ^cleanMethodArgument[] $_sql[$aOptions.sql] $_binPath[^file:dirname[$__HYDCORE_FILESPEC__]/../bin] ^defReadProperty[binPath] $_coreRootPath[^file:dirname[$__HYDCORE_ABSOLUTE_FILESPEC__]] ^defReadProperty[coreRootPath] $_storagePath[^file:dirname[$__HYDCORE_FILESPEC__]/../../../hydra-storage] ^defReadProperty[storagePath] $_modules[^hash::create[]] ^addModule[regions;hydCoreRegions] ^addModule[counters;hydCoreCounters] ^addModule[mc;hydCoreManagementCompanies] ^addModule[vts;hydCoreVTS] ^addModule[feedback;hydCoreFeedback] ^addModule[payments;hydCorePayments] ^addModule[debts;hydCoreDebts] ^addModule[reports;hydCoreReports] ^addModule[logs;hydCoreLogs] $_speechKitKey[...] ^addModule[utils;hydCoreUtils; $.args[ $.yandexSpeechkitKey[$_speechKitKey] ] ] ^addModule[security;hydCoreSecurity; $.args[ $.secretKey[...] $.cryptKey[...] ] ] $_sphinxDaemonAddress[127.0.0.1:9306] ^addModule[search;hydCoreSearch; $.args[ $.sphinxAddress[$_sphinxDaemonAddress] ] ] ^addModule[settings;pfSQLSettings; $.path[pf/sql/generics/settings/pfSQLSettings.p] $.args[ $.sql[$_sql] $.ignoreKeyCase(true) ] ] $_uiTypes[ $._default[ $.id[0] $.title[] ] $.hydra[ $.id[1] $.title[Гидра] ] $.terminal[ $.id[2] $.title[Терминал] ] $.web[ $.id[3] $.title[Интернет] ] ] ^defReadProperty[uiTypes] @GET_CSQL[] $result[$_sql] @GET_speechKit[] ^if(!def $_speechKit){ ^use[pf/api/yandex/speechkit/pfYandexSpeechKit.p] $_speechKit[^pfYandexSpeechKit::create[$_speechKitKey]] } $result[$_speechKit] @addModule[aModuleName;aClassName;aOptions] ## aOptions.path ## aOptions.args ^cleanMethodArgument[] $_modules.[$aModuleName][$.className[$aClassName] $.object[] $.options[$aOptions]] @getModule[aName] ^if(^_modules.contains[$aName]){ ^if(!def $_modules.[$aName].object){ $_modules.[$aName].object[^_coreFabric[$_modules.[$aName].className;$_modules.[$aName].options]] } $result[$_modules.[$aName].object] }{ ^throw[hydCore.fail;Модуль "$aName" не найден.] } @GET_DEFAULT[aName] $result[] ^if(^_modules.contains[$aName]){ ^if(!def $_modules.[$aName].object){ $_modules.[$aName].object[^_coreFabric[$_modules.[$aName].className;$_modules.[$aName].options]] } $result[$_modules.[$aName].object] } @_coreFabric[aClass;aOptions] ^use[^if(def $aOptions.path){$aOptions.path}{hydra/${aClass}.p}] $result[^reflection:create[$aClass;create;^hash::create[$aOptions.args] $.core[$self]]]app/models/hydBaseModel.p:
@USE pf/types/pfClass.p pf/sql/orm/pfSQLTable.p ## Базовая модель @CLASS hydBaseModel @BASE pfClass @create[aOptions] ## aOptions.core ^cleanMethodArgument[] ^pfAssert:isTrue($aOptions.core is hydCore)[core должен быть наследником hydCore.] $_options[$aOptions] $_core[$aOptions.core] $_now[^date::now[]] $_today[^date::today[]] $_modules[^hash::create[]] #----- Properties ----- @GET_core[] $result[$_core] @GET_CSQL[] $result[$core.CSQL] @GET_precision[] $result[%.3f] #----- Modules ----- @GET_DEFAULT[aName][locals] $result[^getModule[$aName]] @addModule[aModuleName;aClassName;aOptions] ^cleanMethodArgument[] $_modules.[$aModuleName][$.className[$aClassName] $.object[] $.options[$aOptions]] @_moduleFabric[aClass;aOptions] ^unsafe{^use[hydra/${aClass}.p]} $result[^reflection:create[^file:justname[$aClass];create;^hash::create[$aOptions] $.core[$_core]]] @getModule[aName] ^if(^_modules.contains[$aName]){ ^if(!def $_modules.[$aName].object){ $_modules.[$aName].object[^_moduleFabric[$_modules.[$aName].className;$_modules.[$aName].options]] } $result[$_modules.[$aName].object] }{ ^throw[hydBaseModel.fail;Модуль "$aName" не найден.] } # Модель, наследник pfSQLTable, но реализующая интерфейс hydBaseModel @CLASS hydDBTable @BASE pfSQLTable @create[aOptions] ## aOptions.tableName ## aOptions.core ^cleanMethodArgument[] ^pfAssert:isTrue(def $aOptions.core && $aOptions.core is hydCore)[core должен быть наследником hydCore.] $_core[$aOptions.core] $_options[$aOptions] $_now[^date::now[]] $_today[^date::today[]] ^BASE:create[^if(def $aOptions.tableName){$aOptions.tableName};^hash::create[$aOptions] $.sql[$_core.CSQL]] $_modules[^hash::create[]] #----- Properties ----- @GET_core[] $result[$_core] @GET_precision[] $result[%.3f] #----- Modules ----- @GET_DEFAULT[aName][locals] ^if(^_modules.contains[$aName]){ $result[^getModule[$aName]] }{ $result[^BASE:GET_DEFAULT[$aName]] } @addModule[aModuleName;aClassName;aOptions] ^cleanMethodArgument[] $_modules.[$aModuleName][$.className[$aClassName] $.object[] $.options[$aOptions]] @_moduleFabric[aClass;aOptions] ^unsafe{^use[hydra/${aClass}.p]} $result[^reflection:create[^file:justname[$aClass];create;^hash::create[$aOptions] $.core[$_core]]] @getModule[aName] ^if(^_modules.contains[$aName]){ ^if(!def $_modules.[$aName].object){ $_modules.[$aName].object[^_moduleFabric[$_modules.[$aName].className;$_modules.[$aName].options]] } $result[$_modules.[$aName].object] }{ ^throw[hydDBTable.fail;Модуль "$aName" не найден.] }Дальше пошло «мясо», которое и реализует бизнес-правила.
@CLASS hydCoreRegions @BASE hydDBTable @create[aOptions][locals] ^BASE:create[^hash::create[$aOptions] $.tableName[regions] $.tableAlias[reg] # $.allAsTable(true) ] ^addFields[ $.regionID[$.dbField[region_id] $.primary(true) $.sequence(false) $.processor[uint] $.label[Код] $.plural[regions]] $.name[$.label[Название района] $.default[___ Безымянный район __]] $.districtID[$.dbField[district_id] $.plural[districts] $.processor[uint_null] $.label[Округ] $.widget[select]] $.slug[$.widget[none]] $.comment[$.label[Комментарий] $.widget[textarea]] $.lastImport[$.dbField[last_import] $.processor[datetime] $.widget[none]] $.allowWeb[$.dbField[allow_web] $.processor[bool] $.default(false) $.label[Доступ из веб-терминала] $.widget[checkbox]] $.firstDay[$.dbField[first_day] $.processor[uint] $.default(0) $.label[Начало приема]] $.deadlineDay[$.dbField[deadline_day] $.processor[uint] $.default(0) $.label[Окончание приема]] $.waterDelta[$.dbField[water_delta] $.processor[uint] $.default(0) $.label[Максимальная разница]] $.waterMonthes[$.dbField[water_monthes] $.processor[uint] $.default(0) $.label[Акт снятия каждые]] $.firstActionDate[$.dbField[first_action_date] $.processor[date] $.label[]] $.housesCnt[$.dbField[houses_cnt] $.processor[uint] $.widget[none]] $.flatesCnt[$.dbField[flates_cnt] $.processor[uint] $.widget[none]] $.accountsCnt[$.dbField[accounts_cnt] $.processor[uint] $.widget[none]] $.waterCountersCnt[$.dbField[water_counters_cnt] $.processor[uint] $.widget[none]] $.waterFlatesCnt[$.dbField[water_flates_cnt] $.processor[uint] $.widget[none]] $.smsPhonesCnt[$.dbField[sms_phones_cnt] $.processor[uint] $.label[]] $.title1[$.dbField[title_1] $.label[Что]] $.title2[$.dbField[title_2] $.label[Где (в)]] $.title3[$.dbField[title_3] $.label[Кого]] $.titleSMS[$.dbField[title_sms] $.expression[(case when title_sms != "" then title_sms else title_2 end)] $.label[Для СМС, где (в)]] $.phones[$.label[Телефоны]] $.createdAt[$.dbField[created_at] $.processor[auto_now] $.skipOnUpdate(true) $.widget[none]] $.updatedAt[$.dbField[updated_at] $.processor[auto_now] $.widget[none]] ] $lFirstDayOfMonth[^date::create($_today.year;$_today.month;1)] $lFirstDayOfMonth[^lFirstDayOfMonth.sql-string[date]] ^addFields[ $.deadlineDate[ $.expression[ (date_sub(case when $deadlineDay > 0 and $deadlineDay < $firstDay then date_add(date_add("$lFirstDayOfMonth", interval $deadlineDay - 1 day), interval 1 month) when deadline_day > 0 and date_add("$lFirstDayOfMonth", interval $deadlineDay - 1 day) < last_day("^_today.sql-string[date]") then date_add("$lFirstDayOfMonth", interval $deadlineDay - 1 day) else last_day("^_today.sql-string[date]") end, interval if($deadlineDay < $firstDay and $_today.day <= $deadlineDay, 1, 0) month)) ] $.widget[none] ] $.firstDate[ $.expression[ (date_sub(case when $firstDay > 0 and date_add("$lFirstDayOfMonth", interval $firstDay - 1 day) <= last_day("^_today.sql-string[date]") then date_add("$lFirstDayOfMonth", interval $firstDay - 1 day) else "$lFirstDayOfMonth" end, interval if($deadlineDay < $firstDay and $_today.day <= $deadlineDay, 1, 0) month)) ] $.widget[none] ] $.aggregateDate[ $.expression[ (case when $deadlineDay < $firstDay and $_today.day <= $deadlineDay then date_sub("$lFirstDayOfMonth", interval 1 month) else "$lFirstDayOfMonth" end) ] ] ] $lSettingsModule[^core.getModule[settings]] $lDefaultWebSite[$lSettingsModule.web_site] ^addModule[districts;hydCoreRegionsDistricts] $lDistricts[^getModule[districts]] ^addFields[ $.district[ $.expression[$lDistricts.name] $.widget[none] ] $.districtSlug[ $.expression[$lDistricts.slug] $.widget[none] ] $.districtOrder[ $.expression[$lDistricts.order] $.widget[none] ] $.districtTitle[ $.expression[$lDistricts.title] $.widget[none] ] $.smsSystem[ $.expression[$lDistricts.smsSystem] $.widget[none] ] $.webSite[ $.expression[if($lDistricts.webSite != "", $lDistricts.webSite, "^taint[$lDefaultWebSite]")] $.widget[none] ] ] $self._defaultOrderBy[$.districtOrder[asc] $.name[asc] $.regionID[asc]] ^addModule[streets;hydCoreRegionsStreets] ^addModule[houses;hydCoreRegionsHouses] ^addModule[flates;hydCoreRegionsFlates] ^addModule[accounts;hydCoreRegionsAccounts] ^addModule[terminals;hydCoreRegionsTerminals] $self._asuCharset[windows-1251] @_allJoin[aOptions] $result[^BASE:_allJoin[$aOptions] left join $districts.TABLE_EXPRESSION on $districtID = $districts.districtID ] #--------------------------------------------------------------------------- @CLASS hydCoreRegionsDistricts @BASE hydDBTable @create[aOptions] ^BASE:create[^hash::create[$aOptions] $.tableName[districts] $.tableAlias[dstr] $.allAsTable(true) ] ^addFields[ $.districtID[$.dbField[district_id] $.plural[districts] $.processor[uint] $.primary(true) $.widget[none]] $.name[$.label[]] $.title[$.label[]] $.slug[$.label[]] $.smsSystem[$.dbField[sms_system] $.label[]] $.webSite[$.dbField[web_site] $.label[]] $.order[$.processor[uint] $.label[]] ] $_defaultOrderBy[$.order[asc] $.name[asc]] #--------------------------------------------------------------------------- @CLASS hydCoreRegionsStreets @BASE hydDBTable @create[aOptions] ^BASE:create[^hash::create[$aOptions] $.tableName[regions_streets] $.tableAlias[str] $.allAsTable(true) ] ^addFields[ $.streetID[$.dbField[street_id] $.primary(true) $.sequence(false) $.processor[uint] $.plural[streets]] $.streetName[$.dbField[street_name]] $.createdAt[$.dbField[created_at] $.processor[auto_now] $.skipOnUpdate(true)] $.updatedAt[$.dbField[updated_at] $.processor[auto_now]] ] $self._defaultOrderBy[$.streetName[asc] $.streetID[asc]] #--------------------------------------------------------------------------- @CLASS hydCoreRegionsHouses @BASE hydDBTable @create[aOptions][locals] ^BASE:create[^hash::create[$aOptions] $.tableName[regions_houses] $.tableAlias[hs] $.allAsTable(true) ] $lRegions[^core.getModule[regions]] $lStreets[^lRegions.getModule[streets]] ^addFields[ $.houseID[$.dbField[house_id] $.primary(true) $.sequence(false) $.processor[uint] $.plural[houses]] $.houseBtiID[$.dbField[house_bti_id] $.processor[uint]] $.streetID[$.dbField[street_id] $.processor[uint] $.plural[streets]] $.houseNumber[$.dbField[house_number]] $.houseStr[$.dbField[house_str]] $.houseKorp[$.dbField[house_korp]] $.regionID[$.dbField[region_id] $.plural[regions] $.processor[uint]] $.createdAt[$.dbField[created_at] $.processor[auto_now] $.skipOnUpdate(true)] $.updatedAt[$.dbField[updated_at] $.processor[auto_now]] $.__houseKey[$.dbField[__house_key] $.widget[none]] ] # Вычисляемые поля ^addField[streetName;$.expression[$lStreets.streetName]] ^addField[address; $.expression[ concat($lStreets.streetName, ", д. ", $houseNumber, if($houseKorp != "", concat(", корп. ", $houseKorp), ""), if($houseStr != "", concat(", стр. ", $houseStr), "") ) ] ] ^addField[building; $.expression[ concat($houseNumber, if($houseKorp != "", concat(", корп. ", $houseKorp), ""), if($houseStr != "", concat(", стр. ", $houseStr), "") ) ] ] $self._defaultOrderBy[$.streetName[asc] $.houseNumber[asc] $.houseKorp[asc] $.houseStr[asc]] @_allJoin[aOptions] $result[join $core.regions.streets.TABLE_EXPRESSION on ($streetID = $core.regions.streets.streetID)] #--------------------------------------------------------------------------- @CLASS hydCoreRegionsFlates @BASE hydDBTable @create[aOptions][locals] ^BASE:create[^hash::create[$aOptions] $.tableName[regions_flates] $.tableAlias[flt] $.allAsTable(true) ] $lRegions[^core.getModule[regions]] $lStreets[^lRegions.getModule[streets]] $lHouses[^lRegions.getModule[houses]] $lAccounts[^lRegions.getModule[accounts]] ^addFields[ $.flatID[$.dbField[flat_id] $.primary(true) $.sequence(false) $.processor[uint] $.plural[flates]] $.regionID[$.dbField[region_id] $.plural[regions] $.processor[uint] $.label[]] $.asuFlatID[$.dbField[asu_flat_id] $.processor[uint] $.label[]] $.houseID[$.dbField[house_id] $.processor[uint] $.plural[houses]] $.flatNumber[$.dbField[flat_number]] $.createdAt[$.dbField[created_at] $.processor[auto_now] $.skipOnUpdate(true)] $.updatedAt[$.dbField[updated_at] $.processor[auto_now]] $.__houseKey[$.dbField[__house_key] $.widget[none]] # Поля для выборок $.accountID[$.fieldExpression[$lAccounts.accountID] $.widget[none]] ] # Вычисляемые поля ^addField[address; $.expression[ concat($lStreets.streetName, ", д. ", $lHouses.houseNumber, if($lHouses.houseKorp != "", concat(", корп. ", $lHouses.houseKorp), ""), if($lHouses.houseStr != "", concat(", стр. ", $lHouses.houseStr), ""), if($flatNumber != "", concat(", кв. ", $flatNumber), "") ) ] ] ^addField[house; $.expression[ concat($lStreets.streetName, ", д. ", $lHouses.houseNumber, if($lHouses.houseKorp != "", concat(", корп. ", $lHouses.houseKorp), ""), if($lHouses.houseStr != "", concat(", стр. ", $lHouses.houseStr), "") ) ] ] ^addField[accounts; $.expression[group_concat(distinct $lAccounts.accountID separator ", ")] ] $self._defaultGroupBy[flatID] $self._defaultOrderBy[flatID+1] @_allJoin[aOptions] $result[ join $core.regions.houses.TABLE_EXPRESSION on ($houseID = $core.regions.houses.houseID) join $core.regions.streets.TABLE_EXPRESSION on ($core.regions.houses.streetID = $core.regions.streets.streetID) left join $core.regions.accounts.TABLE_EXPRESSION on ($flatID = $core.regions.accounts.flatID) ] @similarTo[aFlat;aOptions] ## Ищет квартиры, «похожие» на образец ## aOptions.includeSelf(false) — ыулючить в результат квартиру-источник ## aOptions.phones — номера телефонов ## aOptions.regions[] — доступные районы ^cleanMethodArgument[] $result[^hash::create[]] ^if(^aOptions.contains[phones] && $aOptions.phones){ $result[^all[ ^if($aOptions.regions){ $.regions[$aOptions.regions] } ^if(!^aOptions.includeSelf.bool(false)){ $.[flatID !=][$aFlat.flatID] } $.[flatID in][^core.feedback.sms.phones.aggregate[_fields(flatID); $.[number in][$aOptions.phones] $.isActive(true) ]] $.orderBy[$.address[asc]] ]] } #--------------------------------------------------------------------------- @CLASS hydCoreRegionsAccounts @BASE hydDBTable @create[aOptions][locals] ^BASE:create[^hash::create[$aOptions] $.tableName[regions_accounts] $.tableAlias[acc] $.allAsTable(true) ] ^addFields[ $.accountID[$.dbField[account_id] $.widget[none]] $.flatID[$.dbField[flat_id] $.processor[uint] $.widget[none]] $.regionID[$.dbField[region_id] $.plural[regions] $.processor[uint] $.widget[none]] $.asuFlatID[$.dbField[asu_flat_id] $.processor[uint] $.label[]] $.createdAt[$.dbField[created_at] $.processor[auto_now] $.skipOnUpdate(true) $.widget[none]] $.updatedAt[$.dbField[updated_at] $.processor[auto_now] $.widget[none]] ] #--------------------------------------------------------------------------- @CLASS hydCoreRegionsTerminals @BASE hydDBTable @create[aOptions][locals] ^BASE:create[^hash::create[$aOptions] $.tableName[regions_terminals] $.tableAlias[reg_term] $.allAsTable(true) ] $self._statuses[ $.unset[$.id[0] $.title[Не установлен] $.badge[не установлен] $.class[] $.btnClass[]] $.enabled[$.id[1] $.title[Работает] $.badge[работает] $.class[success] $.btnClass[success]] $.disabled[$.id[2] $.title[Выключен] $.badge[выключен] $.class[important] $.btnClass[danger]] $.repair[$.id[3] $.title[В ремонте] $.badge[в ремонте] $.class[warning] $.btnClass[warning]] ] ^defReadProperty[statuses] $self._rdProtos[ $.rdp[$.id[1] $.title[Remote desktop (Windows)] $.uriPrefix[rdp://]] $.vnc[$.id[2] $.title[VNC] $.uriPrefix[vnc://]] $.ssh[$.id[3] $.title[Secure shell (SSH)] $.uriPrefix[ssh://]] $.telnet[$.id[4] $.title[Telnet] $.uriPrefix[telnet://]] ] ^defReadProperty[rdProtos] ^addFields[ $.terminalID[$.dbField[terminal_id] $.plural[terminals] $.processor[uint] $.primary(true) $.widget[none]] $.description[$.default[__Неизвестный терминал__] $.label[Место установки]] $.ip[$.dbField[ip] $.expression{inet_ntoa(^_builder.quoteIdentifier[$TABLE_ALIAS].^_builder.quoteIdentifier[ip])} $.processor[inet_ip] $.label[IP-адрес]] $.regionID[$.dbField[region_id] $.plural[regions] $.processor[uint_null] $.label[Район] $.widget[select]] $.comment[$.label[Комментарий] $.widget[textarea]] $.externalIP[$.dbField[external_ip] $.expression{inet_ntoa(^_builder.quoteIdentifier[$TABLE_ALIAS].^_builder.quoteIdentifier[external_ip])} $.processor[inet_ip] $.label[«Внешний» IP]] $.rdPort[$.dbField[rd_port] $.processor[uint_null] $.label[Порт]] $.isActive[$.dbField[is_active] $.processor[bool] $.default(1) $.widget[none]] $.createdAt[$.dbField[created_at] $.processor[auto_now] $.skipOnUpdate(true) $.widget[none]] $.updatedAt[$.dbField[updated_at] $.processor[auto_now] $.widget[none]] ] ^addFields[ $.status[ $.dbField[status] $.processor[uint] $.widget[none] $.expression[(case ^_builder.quoteIdentifier[$TABLE_ALIAS].^_builder.quoteIdentifier[status] ^_statuses.foreach[k;v]{when ^v.id.int(-1) then "^taint[$k]"}[ ] else 0 end)] ] ] ^addFields[ $.rdProtocol[ $.dbField[rd_protocol] $.processor[uint] $.label[Протокол удаленного доступа] $.widget[select] $.expression[(case ^_builder.quoteIdentifier[$TABLE_ALIAS].^_builder.quoteIdentifier[rd_protocol] ^_rdProtos.foreach[k;v]{when ^v.id.int(-1) then "^taint[$k]"}[ ] else 0 end)] ] ] $self._defaultOrderBy[(case when $regionID is null then 100000 else $regionID end) asc, $description asc, $ip asc] @delete[aTerminalID] $result[^modify[$aTerminalID; $.isActive(false) $.status[$_statuses.unset.id] ]] @restore[aTerminalID] $result[^modify[$aTerminalID;$.isActive(true)]]И кусочек из сервисной модельки.
@CLASS hydCoreUtils ## Полезные функции. @USE hlpFormater.p pf/types/pfString.p @BASE hydBaseModel @OPTIONS locals @create[aOptions] ## aOptions.yandexSpeechkitKey[] ^cleanMethodArgument[] ^BASE:create[$aOptions] $self._whoisScript[$core.binPath/whois] $self._regex[ $.numeric[^regex::create[^^\s*\-?\s*([\d\s]+)\s*(?:(?:[\.\,]\s*)(\d+))?.*^$]] $.weight[^regex::create[^^[-+]?\s*(\d[\d\s]*)(?:[\.,ю]\s*(\d+))?\s*(\p{L})?][i]] $.allSpaces[^regex::create[\s+][g]] $.phone1[^regex::create[((?:\d\-)?[\d\-]+\d)][g]] $.phone2[^regex::create[((?:\+?[78]\s*)?\(\d+\)\s*[\d\-]+\d)][g]] $.phone3[^regex::create[(?:[78])(\d{10})][g]] $.hexValue[^regex::create[^^[0-9a-zA-Z]*^$][n]] ] $self._formater[^hlpFormater::create[]] ^defReadProperty[formater] $self.parseFailException[core.utils.parse.fail] ^addModule[speechkit;utils/hydCoreUtilsSpeechkit; $.yandexSpeechkitKey[$aOptions.yandexSpeechkitKey] ] ^addModule[phonesConverter;utils/hydCoreUtilsPhonesConverter] #----- Strings ----- @cleanPhones[aPhones;aOptions] ## aOptions.removePrefix(false) - удалить ведущий префикс (7, 8) $result[^aPhones.match[$_regex.phone1][]{^match.1.match[[\-]][g][]}] $result[^result.match[$_regex.phone2][]{^match.1.match[[\-\+\(\)\s]][g][]}] ^if(^aOptions.removePrefix.bool(false)){ $result[^result.match[$_regex.phone3][]{$match.1}] } @cleanMAC[aMAC] ## Удаляет из МАК-адреса лишние символы $result[] $aMAC[^aMAC.match[[\s:\-_\.]+][gi][]] ^if(^aMAC.match[^^[a-fA-F0-9]{12}^$][n]){ $result[^aMAC.lower[]] } @buildTrigrams[aWord] $aWord[__${aWord}__] $result[^for[i](0;^aWord.length[]-3){^aWord.mid($i;3)}[ ]] @levenshtein[aStr1;aStr2] ## Возвращает «расстояние Левеншетйна» между двумя строками $result(^pfString:levenshteinDistance[$aStr1;$aStr2]) @levenshteinForTable[aStr;aTable;aColumnName] ## Возвращает расстояния Левенштейна между aStr и всеми значениями колонки aColumnName в aTable ## aColumnName[keyword] — имя колонки в таблице ^if(!def $aColumnName){$aColumnName[keyword]} $result[^hash::create[]] ^aTable.menu{ $result.[^aTable.line[]][^levenshtein[$aTable.[$aColumnName]]] } @levenshteinRatio[aStr1;aStr2][locals] ## Возвращает «расстояние Левеншетйна» между двумя строками в процентах $lLen1(^aStr1.length[]) $lLen2(^aStr2.length[]) $lMaxLen(^if($lLen1 > $lLen2){$lLen1}{$lLen2}) $result(^math:round((1 - (^levenshtein[$aStr1;$aStr2] / $lMaxLen)) * 100)) @splitByWord[aStr;aOptions][locals] ## Разбирает строку на слова ## aOptions.convertLayoutTo[] — преобразовать раскладку ## aOptions.stripSpecial(false) — удалить служебные символы ^cleanMethodArgument[] $result[^hash::create[]] $lConvertLayoutTo[$aOptions.convertLayoutTo] $lStripSpecial(^aOptions.stripSpecial.bool(false)) ^if(def $lConvertLayoutTo){ $aStr[^convertLayout[$lConvertLayoutTo;^aStr.trim[both]]] } $lParts[^aStr.split[ ;lv]] ^lParts.menu{ $lWord[^lParts.piece.trim[both]] ^if($lStripSpecial){ $lWord[^lWord.match[[\p{P}]+][g][ ]] $lWord[^lWord.trim[both]] } $result.[^result._count[]][^lWord.lower[]] } @convertLayout[aLayout;aString][lRus;lEng;lFrom;lTo;lRegex] ## aLayout[lat|rus] - в какой раскладке хотим получить результат $result[] ^if(def $aString){ $lEng[qwertyuiop[]asdfghjkl^;'zxcvbnm,.<>{}:"`~] $lRus[йцукенгшщзхъфывапролджэячсмитьбюбюхъжэёё] ^if($aLayout eq "rus"){ $lFrom[$lEng^lEng.upper[]] $lTo[$lRus^lRus.upper[]] $lRegex[^taint[regex][$lEng]] }{ $lFrom[$lRus^lRus.upper[]] $lTo[$lEng^lEng.upper[]] $lRegex[^taint[regex][$lRus]] } $result[^aString.match[([$lRegex])][gi]{^lTo.mid(^lFrom.pos[$match.1];1)}] } @parseHexValue[aString;aOptions] ## Возвращает число из строки с шестнадуцатиричным значением ## aOptions.maxWidth[] — максимальное количество цифр в числе ## aOptions.allowEmpty(true) — допустимы пустые значения (преобразуется в 0) ^cleanMethodArgument[] $aString[^aString.match[[\p{P}\s]+][g][]] ^if(!^aString.match[$_regex.hexValue] || ($aOptions.maxWidth && ^aString.length[] > ^aOptions.maxWidth.int(0)) || (!^aOptions.allowEmpty.bool(true) && !^aString.length[]) ){ ^throw[$parseFailException;Не удалось преобразовать $aString в число.] } $result(^if(def $aString){^math:convert[$aString](16;10)}{0}) #----- Dates ----- @monthRange[aDate][locals] ## Возвращает диапазон первую и конечную дату месяца для aDate ## result[$.first $.last] $result[^hash::create[]] $lDate[^date::create[$aDate]] $result.first[^date::create($lDate.year;$lDate.month;1;0;0;0)] $result.last[^date::create($lDate.year;$lDate.month;^lDate.last-day[];23;59;59)] @weeks[aDate;aOptions][locals] ## Вычисляем недели относительно aDate ## aOptions.before(0) — недель до ## aOptions.after(0) — недель после ## result[$.[year_num,week_num][$.monday $.sunday $weekYear $.current(bool)]] $result[^hash::create[]] $aDate[^if(def $aDate){^date::create[$aDate]}{$_today}] $lCurMonday[^date::create[^aDate.sql-string[date]]] ^lCurMonday.roll[day](-1 * ^if($lCurMonday.weekday > 0)($lCurMonday.weekday - 1)(6)) $lBefore(^aOptions.before.int(0)) $lAfter(^aOptions.after.int(0)) $lMonday[^date::create[$lCurMonday]] ^lMonday.roll[day](-7*$lBefore) ^for[i](1;$lBefore + $lAfter + 1){ $result.[$lMonday.year,^lMonday.week.format[%02d]][^weekFor[$lMonday]] ^lMonday.roll[day](+7) } @weekFor[aDate][locals] ## Вычисляет данные для недели по дате ## result[hash] $aDate[^if(def $aDate){^date::create[$aDate]}{$_today}] $lMonday[^date::create[^aDate.sql-string[date]]] ^lMonday.roll[day](-1 * ^if($lMonday.weekday > 0)($lMonday.weekday - 1)(6)) $result[ $.week[$lMonday.week] $.year[$lMonday.weekyear] $.monday[^date::create[$lMonday]] $.sunday[^date::create[$lMonday]] $.current($lMonday.weekyear == $_today.weekyear && $lMonday.week == $_today.week) ] ^result.sunday.roll[day](+6) @getWeek[aYear;aWeek][locals] ## Получает неделю по номеру $lDate[^date::create($aYear;1;1)] ^if($lDate != 1){ ^lDate.roll[day](+7) } ^lDate.roll[day](7 * ($aWeek - 1)) $result[^weekForDate[$lDate]] @fromUTC[aDatetime][locals] ## Возвращает время из UTC в зоне сервера. $lUTCNow[^date::create[$_now]] ^lUTCNow.roll[TZ;UTC] $result[^date::create(^date::create[$aDatetime] + ($_now - ^date::create($lUTCNow.year;$lUTCNow.month;$lUTCNow.day;$lUTCNow.hour;$lUTCNow.minute;$lUTCNow.second)))] #----- Parsers ----- @parseNumeric[aSumma;aPrecision;aDefault] ## Парсит сумму ## aPrecision(2) - точность $result[^aSumma.match[$_regex.numeric][]{^match.1.match[$_regex.allSpaces][][]^if(def $match.2){.${match.2}}}] $result[^eval(^result.double(^aDefault.double(0)))[%.^aPrecision.int(2)f]] #----- Networks ----- @whois[aObject][lExec] $result[] $lExec[^file::exec[$_whoisScript;;$aObject]] ^if($lExec.status == 0){ $result[^unsafe{^lExec.text.match[^^#.*?\n+][gm][]}{$lExec.text}] }