Server IP : 80.87.202.40 / Your IP : 216.73.216.169 Web Server : Apache System : Linux rospirotorg.ru 5.14.0-539.el9.x86_64 #1 SMP PREEMPT_DYNAMIC Thu Dec 5 22:26:13 UTC 2024 x86_64 User : bitrix ( 600) PHP Version : 8.2.27 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : ON Directory : /home/bitrix/ext_www/ilovecveti.ru/bitrix/modules/esol.importxml/lib/ |
Upload File : |
<?php namespace Bitrix\EsolImportxml; use Bitrix\Main\Loader; use Bitrix\Main\Localization\Loc; Loc::loadMessages(__FILE__); class Profile { protected static $moduleId = 'esol.importxml'; protected static $moduleFilePrefix = 'esol_import_xml'; protected static $dbIsPrepared = false; protected static $instance = array(); private $params = array(); private $errors = array(); private $entity = false; private $pid = null; private $importMode = null; function __construct($suffix='') { static::PrepareDB(); $this->suffix = $suffix; $this->pathProfiles = dirname(__FILE__).'/../../profiles'.(strlen($suffix) > 0 ? '_'.$suffix : '').'/'; $this->CheckStorage(); $this->tmpdir = $_SERVER["DOCUMENT_ROOT"].'/upload/tmp/'.static::$moduleId.'/'; CheckDirPath($this->tmpdir); $this->uploadDir = $_SERVER["DOCUMENT_ROOT"].'/upload/'.static::$moduleId.'/'; CheckDirPath($this->uploadDir); foreach(array($this->tmpdir, $this->uploadDir) as $k=>$v) { $i = 0; while(++$i < 10 && strlen($v) > 0 && !file_exists($v) && dirname($v)!=$v) { $v = dirname($v); } if(strlen($v) > 0 && file_exists($v) && !is_writable($v)) { $this->errors[] = sprintf(Loc::getMessage('ESOL_IX_DIR_NOT_WRITABLE'), $v); } } $this->tmpdir = realpath($this->tmpdir).'/'; $this->uploadDir = realpath($this->uploadDir).'/'; /*if(!is_writable($this->tmpdir)) $this->errors[] = sprintf(Loc::getMessage('ESOL_IX_DIR_NOT_WRITABLE'), $this->tmpdir); if(!is_writable($this->uploadDir)) $this->errors[] = sprintf(Loc::getMessage('ESOL_IX_DIR_NOT_WRITABLE'), $this->uploadDir);*/ } public static function getInstance($suffix='iblock') { if (!isset(static::$instance[$suffix])) static::$instance[$suffix] = new static($suffix=='iblock' ? '' : $suffix); return static::$instance[$suffix]; } public static function PrepareDB() { if(!static::$dbIsPrepared) { $profileDB = new \Bitrix\EsolImportxml\ProfileTable(); $conn = $profileDB->getEntity()->getConnection(); if(is_callable(array($conn, 'queryExecute'))) { $conn->queryExecute('SET wait_timeout=1800'); $conn->queryExecute('SET sql_mode=""'); } static::$dbIsPrepared = true; } } public function CheckStorage() { $optionName = 'DB_STRUCT_VERSION_'.(strlen($this->suffix) > 0 ? ToUpper($this->suffix) : 'IBLOCK'); $moduleVersion = false; if(is_callable(array('\Bitrix\Main\ModuleManager', 'getVersion'))) { $moduleVersion = \Bitrix\Main\ModuleManager::getVersion(static::$moduleId); if($moduleVersion==\Bitrix\Main\Config\Option::get(static::$moduleId, $optionName)) return; } /*Security filter*/ if(Loader::includeModule('security') && class_exists('\CSecurityFilterMask')) { $mask = '/bitrix/admin/'.static::$moduleFilePrefix.'*'; $findMask = false; $arMasks = array(); $dbRes = \CSecurityFilterMask::GetList(); while($arr = $dbRes->Fetch()) { $arr['MASK'] = $arr['FILTER_MASK']; unset($arr['FILTER_MASK']); if($arr['MASK']==$mask) $findMask = true; if(strlen($arr['SITE_ID'])==0) $arr['SITE_ID'] = 'NOT_REF'; $arMasks[] = $arr; } if(!$findMask) { $arMasks['n0'] = array('MASK'=>$mask, 'SITE_ID'=>'NOT_REF'); \CSecurityFilterMask::Update($arMasks); } } /*Security filter*/ $profileEntity = $this->GetEntity(); $tblName = $profileEntity->getTableName(); $conn = $profileEntity->getEntity()->getConnection(); if(!$conn->isTableExists($tblName)) { $profileEntity->getEntity()->createDbTable(); $conn->query('ALTER TABLE `'.$tblName.'` CHANGE COLUMN `PARAMS` `PARAMS` mediumtext DEFAULT NULL'); $conn->query('ALTER TABLE `'.$tblName.'` CHANGE COLUMN `DATE_START` `DATE_START` datetime DEFAULT NULL'); $conn->query('ALTER TABLE `'.$tblName.'` CHANGE COLUMN `DATE_FINISH` `DATE_FINISH` datetime DEFAULT NULL'); $conn->query('ALTER TABLE `'.$tblName.'` CHANGE COLUMN `SORT` `SORT` int(11) NOT NULL DEFAULT "500"'); $conn->query('ALTER TABLE `'.$tblName.'` CHANGE COLUMN `FILE_HASH` `FILE_HASH` varchar(255) DEFAULT NULL'); $this->CheckTableEncoding($conn, $tblName); } else { $isNewFields = false; $arDbFields = array(); $dbRes = $conn->query("SHOW COLUMNS FROM `" . $tblName . "`"); while($arr = $dbRes->Fetch()) { $arDbFields[] = $arr['Field']; } $fields = $profileEntity->getEntity()->getScalarFields(); $helper = $conn->getSqlHelper(); $prevField = 'ID'; foreach($fields as $columnName => $field) { $realColumnName = $field->getColumnName(); if(!in_array($realColumnName, $arDbFields)) { $conn->query('ALTER TABLE '.$helper->quote($tblName).' ADD COLUMN '.$helper->quote($realColumnName).' '.$helper->getColumnTypeByField($field).' DEFAULT NULL AFTER '.$helper->quote($prevField)); if($field->getDefaultValue()) { $conn->query('UPDATE '.$helper->quote($tblName).' SET '.$helper->quote($realColumnName).'="'.$helper->forSql($field->getDefaultValue()).'"'); } $isNewFields = true; } $prevField = $realColumnName; } if($isNewFields) $this->CheckTableEncoding($conn, $tblName); } /*profile_element*/ $peEntity = $this->GetImportEntity(); $tblName = $peEntity->getTableName(); $conn = $peEntity->getEntity()->getConnection(); if(!$conn->isTableExists($tblName)) { $peEntity->getEntity()->createDbTable(); $conn->query('ALTER TABLE `'.$tblName.'` CHANGE COLUMN `ID` `ID` int(18) NOT NULL AUTO_INCREMENT'); $conn->query('ALTER TABLE `'.$tblName.'` CHANGE COLUMN `TYPE` `TYPE` varchar(1) NOT NULL'); $conn->createIndex($tblName, 'ix_profile_element', array('PROFILE_ID', 'ELEMENT_ID', 'TYPE')); $this->CheckTableEncoding($conn, $tblName); } /*/profile_element*/ /*profile_exec*/ $tEntity = new \Bitrix\EsolImportxml\ProfileExecTable(); $tblName = $tEntity->getTableName(); $conn = $tEntity->getEntity()->getConnection(); if(!$conn->isTableExists($tblName)) { $tEntity->getEntity()->createDbTable(); $conn->query('ALTER TABLE `'.$tblName.'` CHANGE COLUMN `ID` `ID` int(18) NOT NULL AUTO_INCREMENT'); $conn->query('ALTER TABLE `'.$tblName.'` CHANGE COLUMN `DATE_START` `DATE_START` datetime DEFAULT NULL'); $conn->query('ALTER TABLE `'.$tblName.'` CHANGE COLUMN `DATE_FINISH` `DATE_FINISH` datetime DEFAULT NULL'); $conn->query('ALTER TABLE `'.$tblName.'` CHANGE COLUMN `RUNNED_BY` `RUNNED_BY` int(18) DEFAULT NULL'); $conn->query('ALTER TABLE `'.$tblName.'` CHANGE COLUMN `PARAMS` `PARAMS` longtext DEFAULT NULL'); $conn->createIndex($tblName, 'ix_profile_id', array('PROFILE_ID')); $this->CheckTableEncoding($conn, $tblName); } else { $isNewFields = false; $arDbFields = array(); $dbRes = $conn->query("SHOW COLUMNS FROM `" . $tblName . "`"); while($arr = $dbRes->Fetch()) { $arDbFields[] = $arr['Field']; } $fields = $tEntity->getEntity()->getScalarFields(); $helper = $conn->getSqlHelper(); $prevField = 'ID'; foreach($fields as $columnName => $field) { $realColumnName = $field->getColumnName(); if(!in_array($realColumnName, $arDbFields)) { $conn->query('ALTER TABLE '.$helper->quote($tblName).' ADD COLUMN '.$helper->quote($realColumnName).' '.$helper->getColumnTypeByField($field).' DEFAULT NULL AFTER '.$helper->quote($prevField)); if($field->getDefaultValue()) { $conn->query('ALTER TABLE '.$helper->quote($tblName).' CHANGE COLUMN '.$helper->quote($realColumnName).' '.$helper->quote($realColumnName).' '.$helper->getColumnTypeByField($field).' DEFAULT "'.$helper->forSql($field->getDefaultValue()).'"'); $conn->query('UPDATE '.$helper->quote($tblName).' SET '.$helper->quote($realColumnName).'="'.$helper->forSql($field->getDefaultValue()).'"'); } $isNewFields = true; } $prevField = $realColumnName; } if($isNewFields) { $conn->query('ALTER TABLE `'.$tblName.'` CHANGE COLUMN `PARAMS` `PARAMS` longtext DEFAULT NULL'); $this->CheckTableEncoding($conn, $tblName); } } /*/profile_exec*/ /*profile_exec_stat*/ $tEntity = new \Bitrix\EsolImportxml\ProfileExecStatTable(); $tblName = $tEntity->getTableName(); $conn = $tEntity->getEntity()->getConnection(); if(!$conn->isTableExists($tblName)) { $tEntity->getEntity()->createDbTable(); $conn->query('ALTER TABLE `'.$tblName.'` CHANGE COLUMN `ID` `ID` bigint(20) unsigned NOT NULL AUTO_INCREMENT'); $conn->query('ALTER TABLE `'.$tblName.'` CHANGE COLUMN `DATE_EXEC` `DATE_EXEC` datetime DEFAULT NULL'); $conn->query('ALTER TABLE `'.$tblName.'` CHANGE COLUMN `FIELDS` `FIELDS` longtext DEFAULT NULL'); $conn->createIndex($tblName, 'ix_entity_id', array('ENTITY_ID')); $conn->createIndex($tblName, 'ix_profile_id_profile_exec_id', array('PROFILE_ID', 'PROFILE_EXEC_ID')); $this->CheckTableEncoding($conn, $tblName); } else { $isNewFields = false; $arDbFields = array(); $dbRes = $conn->query("SHOW COLUMNS FROM `" . $tblName . "`"); while($arr = $dbRes->Fetch()) { if($arr['Field']=='ID' && $arr['Type'] && mb_stripos($arr['Type'], 'bigint')===false) { $conn->query('ALTER TABLE `'.$tblName.'` CHANGE COLUMN `ID` `ID` bigint(20) unsigned NOT NULL AUTO_INCREMENT'); } $arDbFields[] = $arr['Field']; } $fields = $tEntity->getEntity()->getScalarFields(); $helper = $conn->getSqlHelper(); $prevField = 'ID'; foreach($fields as $columnName => $field) { $realColumnName = $field->getColumnName(); if(!in_array($realColumnName, $arDbFields)) { $conn->query('ALTER TABLE '.$helper->quote($tblName).' ADD COLUMN '.$helper->quote($realColumnName).' '.$helper->getColumnTypeByField($field).' DEFAULT NULL AFTER '.$helper->quote($prevField)); if($field->getDefaultValue()) { $conn->query('ALTER TABLE '.$helper->quote($tblName).' CHANGE COLUMN '.$helper->quote($realColumnName).' '.$helper->quote($realColumnName).' '.$helper->getColumnTypeByField($field).' DEFAULT "'.$helper->forSql($field->getDefaultValue()).'"'); $conn->query('UPDATE '.$helper->quote($tblName).' SET '.$helper->quote($realColumnName).'="'.$helper->forSql($field->getDefaultValue()).'"'); } $isNewFields = true; } $prevField = $realColumnName; } if($isNewFields) { $this->CheckTableEncoding($conn, $tblName); } } /*/profile_exec_stat*/ if($moduleVersion) { \Bitrix\Main\Config\Option::set(static::$moduleId, $optionName, $moduleVersion); } } private function CheckTableEncoding($conn, $tblName) { $res = $conn->query('SHOW VARIABLES LIKE "character_set_connection"'); $f = $res->fetch(); $charset = trim($f['Value']); $res = $conn->query('SHOW VARIABLES LIKE "collation_connection"'); $f = $res->fetch(); $collation = trim($f['Value']); $charset2 = $this->GetCharsetByCollation($conn, $collation); $res0 = $conn->query('SHOW CREATE TABLE `' . $tblName . '`'); $f0 = $res0->fetch(); if (preg_match('/DEFAULT CHARSET=([a-z0-9\-_]+)/i', $f0['Create Table'], $regs)) { $t_charset = $regs[1]; if (preg_match('/COLLATE=([a-z0-9\-_]+)/i', $f0['Create Table'], $regs)) $t_collation = $regs[1]; else { $res0 = $conn->query('SHOW CHARSET LIKE "' . $t_charset . '"'); $f0 = $res0->fetch(); $t_collation = $f0['Default collation']; } } else { $res0 = $conn->query('SHOW TABLE STATUS LIKE "' . $tblName . '"'); $f0 = $res0->fetch(); if (!$t_collation = $f0['Collation']) return; $t_charset = $this->GetCharsetByCollation($conn, $t_collation); } if ($charset != $t_charset) { $conn->query('ALTER TABLE `' . $tblName . '` CHARACTER SET ' . $charset); } elseif ($t_collation != $collation) { // table collation differs $conn->query('ALTER TABLE `' . $tblName . '` COLLATE ' . $collation); } $arFix = array(); $res0 = $conn->query("SHOW FULL COLUMNS FROM `" . $tblName . "`"); while($f0 = $res0->fetch()) { $f_collation = $f0['Collation']; if ($f_collation === NULL || $f_collation === "NULL") continue; $f_charset = $this->GetCharsetByCollation($conn, $f_collation); if ($charset != $f_charset && $charset2 != $f_charset) { $arFix[] = ' MODIFY `'.$f0['Field'].'` '.$f0['Type'].' CHARACTER SET '.$charset.($f0['Null'] == 'YES' ? ' NULL' : ' NOT NULL'). ($f0['Default'] === NULL ? ($f0['Null'] == 'YES' ? ' DEFAULT NULL ' : '') : ' DEFAULT '.($f0['Type'] == 'timestamp' && $f0['Default'] == 'CURRENT_TIMESTAMP' ? $f0['Default'] : '"'.$conn->getSqlHelper()->forSql($f0['Default']).'"')).' '.$f0['Extra']; } elseif ($collation != $f_collation) { $arFix[] = ' MODIFY `'.$f0['Field'].'` '.$f0['Type'].' COLLATE '.$collation.($f0['Null'] == 'YES' ? ' NULL' : ' NOT NULL'). ($f0['Default'] === NULL ? ($f0['Null'] == 'YES' ? ' DEFAULT NULL ' : '') : ' DEFAULT '.($f0['Type'] == 'timestamp' && $f0['Default'] == 'CURRENT_TIMESTAMP' ? $f0['Default'] : '"'.$conn->getSqlHelper()->forSql($f0['Default']).'"')).' '.$f0['Extra']; } } if(count($arFix)) { $conn->query('ALTER TABLE `'.$tblName.'` '.implode(",\n", $arFix)); } } private function GetCharsetByCollation($conn, $collation) { static $CACHE; if (!$c = &$CACHE[$collation]) { $res0 = $conn->query('SHOW COLLATION LIKE "' . $collation . '"'); $f0 = $res0->Fetch(); $c = $f0['Charset']; } return $c; } private function GetEntity() { if(!$this->entity) { if($this->suffix=='highload') { $this->entity = new \Bitrix\EsolImportxml\ProfileHlTable(); } else { $this->entity = new \Bitrix\EsolImportxml\ProfileTable(); } } return $this->entity; } private function GetImportEntity() { if(!$this->importEntity) { if($this->suffix=='highload') { $this->importEntity = new \Bitrix\EsolImportxml\ProfileElementHlTable(); } else { $this->importEntity = new \Bitrix\EsolImportxml\ProfileElementTable(); } } return $this->importEntity; } public function GetList($arFilter=array()) { if(!is_array($arFilter)) $arFilter = array(); if(empty($arFilter)) $arFilter = array('ACTIVE'=>'Y'); $arProfiles = array(); $profileEntity = $this->GetEntity(); $dbRes = $profileEntity::getList(array('select'=>array('ID', 'NAME'), 'order'=>array('SORT'=>'ASC', 'ID'=>'ASC'), 'filter'=>$arFilter)); while($arr = $dbRes->Fetch()) { $arProfiles[$arr['ID'] - 1] = $arr['NAME']; } return $arProfiles; } public function GetByID($ID) { $profileEntity = $this->GetEntity(); $arProfile = $profileEntity::getList(array('filter'=>array('ID'=>($ID + 1)), 'select'=>array('PARAMS')))->fetch(); if($arProfile && $arProfile['PARAMS']) { $arProfile = self::DecodeProfileParams($arProfile['PARAMS']); } if(!is_array($arProfile)) $arProfile = array(); return $arProfile; } public function GetFieldsByID($ID) { if(!is_numeric($ID)) return array(); $profileEntity = $this->GetEntity(); $arProfile = $profileEntity::getList(array('filter'=>array('ID'=>($ID + 1))))->fetch(); unset($arProfile['PARAMS']); return $arProfile; } public function Add($name, $fid = false) { global $APPLICATION; $APPLICATION->ResetException(); $name = trim($name); if(strlen($name)==0) { $APPLICATION->throwException(Loc::getMessage("ESOL_IX_NOT_SET_PROFILE_NAME")); return false; } $profileEntity = $this->GetEntity(); if($arProfile = $profileEntity::getList(array('filter'=>array('NAME'=>$name), 'select'=>array('ID')))->fetch()) { $APPLICATION->throwException(Loc::getMessage("ESOL_IX_PROFILE_NAME_EXISTS")); return false; } $dbRes = $profileEntity::add(array('NAME'=>$name)); if(!$dbRes->isSuccess()) { $error = ''; if($dbRes->getErrors()) { foreach($dbRes->getErrors() as $errorObj) { $error .= $errorObj->getMessage().'. '; } $APPLICATION->throwException($error); } return false; } else { $ID = $dbRes->getId() - 1; if($fid!==false) { \CFile::UpdateExternalId($fid, 'esol_importxml_'.($this->suffix=='highload' ? 'hl' : '').$ID); } return $ID; } } public function Update($ID, $settigs_default, $settings) { $arProfile = $this->GetByID($ID); $oldIblockId = $arProfile['SETTINGS_DEFAULT']['IBLOCK_ID']; if(is_array($settigs_default) && !empty($settigs_default) && ($settigs_default['IBLOCK_ID'] > 0 || $settigs_default['HIGHLOADBLOCK_ID'] > 0)) { $arProfile['SETTINGS_DEFAULT'] = $settigs_default; } if(is_array($settings) && !empty($settings)) { $arProfile['SETTINGS'] = $settings; } /*Change iblock settings*/ if(($oldIblockId != $arProfile['SETTINGS_DEFAULT']['IBLOCK_ID'] || isset($arProfile['OLD_IBLOCK_DATA'])) && Loader::includeModule('iblock') && class_exists('\Bitrix\Iblock\PropertyTable')) { $iblockId = $arProfile['SETTINGS_DEFAULT']['IBLOCK_ID']; $arPropsNames = array(); $arPropsCodes = array(); $dbRes = \Bitrix\Iblock\PropertyTable::getList(array('filter' => array('=IBLOCK_ID'=>$iblockId, '=ACTIVE'=>'Y'), 'select' => array('ID', 'CODE', 'NAME'))); while($arr = $dbRes->Fetch()) { $arPropsNames[$arr['NAME']] = $arr['ID']; $arPropsCodes[$arr['CODE']] = $arr['ID']; } $arPropRels = array(); if(isset($arProfile['OLD_IBLOCK_DATA'])) { if(isset($arProfile['OLD_IBLOCK_DATA']['PROPS']) && isset($arProfile['OLD_IBLOCK_DATA']['PROPS'][$oldIblockId]) && is_array($arProfile['OLD_IBLOCK_DATA']['PROPS'][$oldIblockId])) { foreach($arProfile['OLD_IBLOCK_DATA']['PROPS'][$oldIblockId] as $k=>$v) { if(isset($arPropsCodes[$v['CODE']])) $arPropRels[$k] = $arPropsCodes[$v['CODE']]; elseif(isset($arPropsNames[$v['NAME']])) $arPropRels[$k] = $arPropsNames[$v['NAME']]; } } unset($arProfile['OLD_IBLOCK_DATA']); } else { $dbRes = \Bitrix\Iblock\PropertyTable::getList(array('filter' => array('=IBLOCK_ID'=>$oldIblockId, '=ACTIVE'=>'Y'), 'select' => array('ID', 'CODE', 'NAME'))); while($arr = $dbRes->Fetch()) { if(isset($arPropsCodes[$arr['CODE']])) $arPropRels[$arr['ID']] = $arPropsCodes[$arr['CODE']]; elseif(isset($arPropsNames[$arr['NAME']])) $arPropRels[$arr['ID']] = $arPropsNames[$arr['NAME']]; } } if(count($arPropRels) > 0) { if(isset($arProfile['SETTINGS']['FIELDS']) && is_array($arProfile['SETTINGS']['FIELDS'])) { foreach($arProfile['SETTINGS']['FIELDS'] as $k=>$v) { if(preg_match('/IP_PROP(\d+)/', $v, $m) && isset($arPropRels[$m[1]])) { $arProfile['SETTINGS']['FIELDS'][$k] = str_replace($m[0], 'IP_PROP'.$arPropRels[$m[1]], $v); } } } if(isset($arProfile['SETTINGS']['PROPERTY_MAP']) && strlen($arProfile['SETTINGS']['PROPERTY_MAP']) > 0) { $arMap = unserialize(base64_decode($arProfile['SETTINGS']['PROPERTY_MAP'])); if(is_array($arMap) && isset($arMap['MAP']) && is_array($arMap['MAP'])) { foreach($arMap['MAP'] as $k=>$v) { if(preg_match('/IP_PROP(\d+)/', $v['ID'], $m) && isset($arPropRels[$m[1]])) { $arMap['MAP'][$k]['ID'] = str_replace($m[0], 'IP_PROP'.$arPropRels[$m[1]], $v['ID']); } } $arProfile['SETTINGS']['PROPERTY_MAP'] = base64_encode(serialize($arMap)); } } } } /*/Change iblock settings*/ $profileEntity = $this->GetEntity(); $profileEntity::update(($ID+1), array('PARAMS'=>self::EncodeProfileParams($arProfile))); } public function UpdateExtra($ID, $extrasettings) { $arProfile = $this->GetByID($ID); if(!is_array($extrasettings)) $extrasettings = array(); $arProfile['EXTRASETTINGS'] = $extrasettings; $profileEntity = $this->GetEntity(); $profileEntity::update(($ID+1), array('PARAMS'=>self::EncodeProfileParams($arProfile))); } public function UpdatePartSettings($ID, $settigs_default=array()) { $arProfile = $this->GetByID($ID); $arProfile['SETTINGS_DEFAULT'] = array_merge($arProfile['SETTINGS_DEFAULT'], $settigs_default); $profileEntity = $this->GetEntity(); $profileEntity::update(($ID+1), array('PARAMS'=>self::EncodeProfileParams($arProfile))); } public function Delete($ID) { $profileEntity = $this->GetEntity(); $profileEntity::delete($ID+1); \Bitrix\EsolImportxml\Utils::DeleteFilesByExtId('esol_importxml_'.($this->suffix=='highload' ? 'hl' : '').$ID); \Bitrix\EsolImportxml\ProfileExecTable::deleteByProfile($ID+1); \Bitrix\EsolImportxml\ProfileExecStatTable::deleteByProfile($ID+1); } public function Copy($ID) { $profileEntity = $this->GetEntity(); $arProfile = $profileEntity::getList(array('filter'=>array('ID'=>($ID + 1)), 'select'=>array('NAME', 'PARAMS')))->fetch(); if(!$arProfile) return false; $newName = $arProfile['NAME'].Loc::getMessage("ESOL_IX_PROFILE_COPY"); $arParams = self::DecodeProfileParams($arProfile['PARAMS']); if($arParams['SETTINGS_DEFAULT']['DATA_FILE'] > 0) { $arParams['SETTINGS_DEFAULT']['DATA_FILE'] = \Bitrix\EsolImportxml\Utils::CopyFile($arParams['SETTINGS_DEFAULT']['DATA_FILE'], true); $arProfile['PARAMS'] = self::EncodeProfileParams($arParams); } $dbRes = $profileEntity::add(array('NAME'=>$newName, 'PARAMS'=>$arProfile['PARAMS'])); if(!$dbRes->isSuccess()) { $error = ''; if($dbRes->getErrors()) { foreach($dbRes->getErrors() as $errorObj) { $error .= $errorObj->getMessage().'. '; } $APPLICATION->throwException($error); } return false; } else { $newId = $dbRes->getId() - 1; return $newId; } } public function Rename($ID, $name) { global $APPLICATION; $APPLICATION->ResetException(); $name = trim($name); if(strlen($name)==0) { $APPLICATION->throwException(Loc::getMessage("ESOL_IX_NOT_SET_PROFILE_NAME")); return false; } $profileEntity = $this->GetEntity(); $profileEntity::update(($ID+1), array('NAME'=>$name)); } public function ProfileExists($ID) { if(!is_numeric($ID)) return false; $profileEntity = $this->GetEntity(); if($arProfile = $profileEntity::getList(array('filter'=>array('ID'=>($ID + 1)), 'select'=>array('ID')))->fetch()) return true; else return false; } public function GetProfilesCronPool() { $arIds = array(); $profileEntity = $this->GetEntity(); $dbRes = $profileEntity::getList(array('filter'=>array('NEED_RUN'=>'Y'), 'select'=>array('ID'), 'order'=>array('DATE_START'=>'ASC'))); while($arr = $dbRes->Fetch()) { $arIds[] = (int)$arr['ID'] - 1; } return $arIds; } public function GetLastImportProfiles($arParams = array()) { $arProfiles = array(); $limit = (int)$arParams["PROFILES_COUNT"]; if($limit<=0) $limit = 10; $profileEntity = $this->GetEntity(); $arFilter = array('!DATE_START'=>false); if($arParams["PROFILES_SHOW_INACTIVE"]!='Y') $arFilter['ACTIVE'] = 'Y'; $dbRes = $profileEntity::getList(array('filter'=>$arFilter, 'select'=>array('ID', 'NAME', 'DATE_START', 'DATE_FINISH', 'PARAMS'), 'order'=>array('DATE_START'=>'DESC'), 'limit'=>$limit)); while($arr = $dbRes->Fetch()) { if(isset($arr['PARAMS'])) { $arr['PARAMS'] = self::DecodeProfileParams($arr['PARAMS']); $arr['SETTINGS_DEFAULT'] = $arr['PARAMS']['SETTINGS_DEFAULT']; unset($arr['PARAMS']); } $arr['ID'] = (int)$arr['ID'] - 1; $arProfiles[] = $arr; } return $arProfiles; } public function UpdateFields($ID, $arFields) { if(!is_numeric($ID)) return false; $profileEntity = $this->GetEntity(); $profileEntity::update(($ID+1), $arFields); } public function UpdateFileHash($ID, $file) { $hash = md5_file($file); $this->UpdateFields($ID, array('FILE_HASH'=>$hash)); } public function ApplyToLists($ID, $listFrom, $listTo) { if(!is_numeric($listFrom) || !is_array($listTo) || count($listTo)==0) return; $listTo = preg_grep('/^\d+$/', $listTo); if(count($listTo)==0) return; $arParams = $this->GetByID($ID); foreach($listTo as $key) { $arParams['SETTINGS']['FIELDS_LIST'][$key] = $arParams['SETTINGS']['FIELDS_LIST'][$listFrom]; $arParams['EXTRASETTINGS'][$key] = $arParams['EXTRASETTINGS'][$listFrom]; } $profileEntity = $this->GetEntity(); $profileEntity::update(($ID+1), array('PARAMS'=>self::EncodeProfileParams($arParams))); } public function GetGadgetStatus($id, $bImported=false) { $arProfile = array(); if(is_array($id)) { $arProfile = $id; $id = $arProfile['ID']; } $tmpfile = $this->tmpdir.$id.($this->suffix ? '_'.$this->suffix : '').'.txt'; if(!file_exists($tmpfile)) { if($bImported) { if(empty($arProfile) || !empty($arProfile['DATE_FINISH'])) return array('STATUS'=>'OK', 'MESSAGE'=>Loc::getMessage("ESOL_IX_STATUS_COMPLETE")); else return array('STATUS'=>'ERROR', 'MESSAGE'=>Loc::getMessage("ESOL_IX_STATUS_FILE_ERROR")); } else return array('STATUS'=>'OK', 'MESSAGE'=>''); } $arParams = $this->GetProfileParamsByFile($tmpfile); $percent = round(((int)$arParams['total_read_line'] / (int)$arParams['total_file_line']) * 100); $percent = min($percent, 99); $status = 'OK'; if((time() - filemtime($tmpfile) < 4*60)) $statusText = Loc::getMessage("ESOL_IX_STATUS_PROCCESS"); else { $statusText = Loc::getMessage("ESOL_IX_STATUS_BREAK"); $status = 'ERROR'; } return array('STATUS'=>'ERROR', 'MESSAGE'=>$statusText.' ('.$percent.'%)'); } public function GetStatus($id) { $tmpfile = $this->tmpdir.$id.($this->suffix ? '_'.$this->suffix : '').'.txt'; if(!file_exists($tmpfile) || filesize($tmpfile)>500*1024) return ''; $arParams = \CUtil::JsObjectToPhp(file_get_contents($tmpfile)); $percent = round(((int)$arParams['total_read_line'] / (int)$arParams['total_file_line']) * 100); $percent = min($percent, 99); if((time() - filemtime($tmpfile) < 4*60)) $status = Loc::getMessage("ESOL_IX_STATUS_PROCCESS"); else $status = Loc::getMessage("ESOL_IX_STATUS_BREAK"); return $status.' ('.$percent.'%)'; } public function GetProfileParamsByFile($tmpfile) { $content = file_get_contents($tmpfile); $maxLength = 10*1024; if(strlen($content) > $maxLength) { $arParams = array(); $content = preg_replace('/(.)\{[^\}]*\}(.)/Uis', '$1$2', $content); if(preg_match_all("/'([^']*)':'([^']*)'/", $content, $m)) { foreach($m[1] as $k2=>$v2) { $arParams[$v2] = $m[2][$k2]; } } } else { $arParams = \CUtil::JsObjectToPhp(file_get_contents($tmpfile)); } return $arParams; } public function GetProcessedProfiles() { $arProfiles = $this->GetList(); foreach($arProfiles as $k=>$v) { $tmpfile = $this->tmpdir.$k.($this->suffix ? '_'.$this->suffix : '').'.txt'; if(!file_exists($tmpfile) || filesize($tmpfile)>500*1024 || (time() - filemtime($tmpfile) < 4*60) || filemtime($tmpfile) < mktime(0, 0, 0, 12, 24, 2015)) { unset($arProfiles[$k]); continue; } $arParams = $this->GetProfileParamsByFile($tmpfile); $percent = round(((int)$arParams['total_read_line'] / max((int)$arParams['total_file_line'], 1)) * 100); $percent = min($percent, 99); $arProfiles[$k] = array( 'key' => $k, 'name' => $v, 'percent' => $percent ); } if(!is_array($arProfiles)) $arProfiles = array(); return $arProfiles; } public function RemoveProcessedProfile($id) { $tmpfile = $this->tmpdir.$id.($this->suffix ? '_'.$this->suffix : '').'.txt'; if(file_exists($tmpfile)) { $arParams = $this->GetProfileParamsByFile($tmpfile); if($arParams['tmpdir']) { DeleteDirFilesEx(substr($arParams['tmpdir'], strlen($_SERVER['DOCUMENT_ROOT']))); } unlink($tmpfile); } } public function GetProccessParams($id) { $tmpfile = $this->tmpdir.$id.($this->suffix ? '_'.$this->suffix : '').'.txt'; if(file_exists($tmpfile)) { $arParams = $this->GetProfileParamsByFile($tmpfile); $paramFile = $arParams['tmpdir'].'params.txt'; if(file_exists($paramFile)) $arParams = unserialize(file_get_contents($paramFile)); return $arParams; } return false; } public function GetProccessParamsFromPidFile($id) { $tmpfile = $this->tmpdir.$id.($this->suffix ? '_'.$this->suffix : '').'.txt'; if(file_exists($tmpfile)) { if(time() - filemtime($tmpfile) < 3*60) { return false; } $arParams = $this->GetProfileParamsByFile($tmpfile); return $arParams; } return array(); } public function SetImportParams($pid, $tmpdir, $arParams, $arImportParams=array()) { $this->pid = $pid; $this->importMode = ($arParams['IMPORT_MODE']=='CRON' ? 'CRON' : 'USER'); $this->importParams = $arImportParams; } public function GetErrors() { if(!isset($this->errors) || !is_array($this->errors)) $this->errors = array(); return implode('<br>', array_unique($this->errors)); } public function ShowProfileList($fname, $PROFILE_ID='') { $arProfiles = $this->GetList(is_numeric($PROFILE_ID) && strlen($PROFILE_ID) > 0 ? array('LOGIC'=>'OR', array('ACTIVE'=>'Y'), array('ID'=>$PROFILE_ID+1)) : array()); ?><select name="<?echo $fname;?>" id="<?echo $fname;?>" onchange="EProfile.Choose(this)"><? ?><option value=""><?echo Loc::getMessage("ESOL_IX_NO_PROFILE"); ?></option><? ?><option value="new" <?if($_REQUEST[$fname]=='new'){echo 'selected';}?>><?echo Loc::getMessage("ESOL_IX_NEW_PROFILE"); ?></option><? foreach($arProfiles as $k=>$profile) { ?><option value="<?echo $k;?>" <?if(strlen($_REQUEST[$fname])>0 && strval($_REQUEST[$fname])===strval($k)){echo 'selected';}?>><?echo $profile; ?></option><? } ?></select><? } public function ShowProfileListAlt($fname, $PROFILE_ID='') { //$arProfiles = $this->GetList(is_numeric($PROFILE_ID) && strlen($PROFILE_ID) > 0 ? array('LOGIC'=>'OR', array('ACTIVE'=>'Y'), array('ID'=>$PROFILE_ID+1)) : array()); $arProfiles = $this->GetList(); ?><select name="<?echo $fname;?>" id="<?echo $fname;?>"><? ?><option value=""><?echo Loc::getMessage("ESOL_IX_NO_PROFILE"); ?></option><? foreach($arProfiles as $k=>$profile) { ?><option value="<?echo $k;?>" <?if(is_numeric($PROFILE_ID) && strlen($PROFILE_ID) > 0 && strval($PROFILE_ID)===strval($k)){echo 'selected';}?>><?echo $profile; ?></option><? } ?></select><? } public function SetParams($params=array()) { $this->params = $params; } public function GetParam($name) { if(isset($this->params[$name])) return $this->params[$name]; return null; } public static function EncodeProfileParams($arParams) { return '='.base64_encode(serialize($arParams)); } public static function DecodeProfileParams($paramStr) { $paramStr = trim($paramStr); if(substr($paramStr, 0, 1)=='=') $paramStr = base64_decode(substr($paramStr, 1)); $arParams = unserialize($paramStr); if(!is_array($arParams)) $arParams = array(); return $arParams; } public function Apply(&$settigs_default, &$settings, $ID) { $arProfile = $this->GetByID($ID); if(!is_array($settigs_default) && is_array($arProfile['SETTINGS_DEFAULT'])) { $settigs_default = $arProfile['SETTINGS_DEFAULT']; } if(!is_array($settings) && is_array($arProfile['SETTINGS'])) { $settings = $arProfile['SETTINGS']; } if(is_array($settings)) { /*Protect of loss setting*/ if(!isset($settings['FIELDS']) && !isset($settings['GROUPS']) && is_array($arProfile['SETTINGS'])) { foreach($arProfile['SETTINGS'] as $k=>$v) { if(!isset($settings[$k])) $settings[$k] = $v; } } /*/Protect of loss setting*/ if($settings['ADDITIONAL_SETTINGS']) { foreach($settings['ADDITIONAL_SETTINGS'] as $k=>$v) { if($v && !is_array($v)) { $v = \CUtil::JsObjectToPhp($v); } if(!is_array($v)) $v = array(); $settings['ADDITIONAL_SETTINGS'][$k] = $v; } } } if(!is_array($settigs_default)) $settigs_default = array(); if(!is_array($settings)) $settings = array(); $instance = static::getInstance(); $instance->SetParams($settigs_default); } public function ApplyExtra(&$extrasettings, $ID) { $arProfile = $this->GetByID($ID); if(!is_array($extrasettings) && is_array($arProfile['EXTRASETTINGS'])) { $extrasettings = $arProfile['EXTRASETTINGS']; } } public function SaveElementId($ID, $type) { $entity = $this->GetImportEntity(); $arFields = array('PROFILE_ID'=>$this->pid, 'ELEMENT_ID'=>$ID); $dbRes = $entity::getList(array('filter'=>array_merge($arFields, array('=TYPE'=>$type)), 'select'=>array('ID'))); if($dbRes->Fetch()) { return false; } else { $entity::add(array_merge($arFields, array('TYPE'=>$type))); return true; } } public function GetLastImportId($type) { $entity = $this->GetImportEntity(); $dbRes = $entity::getList(array('filter'=>array('PROFILE_ID'=>$this->pid, '=TYPE'=>$type), 'runtime' => array('MAX_ID' => array('data_type'=>'float', 'expression' => array('max(%s)', 'ELEMENT_ID'))), 'select'=>array('MAX_ID'))); if($arr = $dbRes->Fetch()) return $arr['MAX_ID']; else return 0; } public function GetUpdatedIds($type, $first) { $entity = $this->GetImportEntity(); $arIds = array(); $dbRes = $entity::getList(array('filter'=>array('PROFILE_ID'=>$this->pid, '=TYPE'=>$type, '>ELEMENT_ID'=>(int)$first), 'select'=>array('ELEMENT_ID'), 'order'=>array('ELEMENT_ID'=>'ASC'), 'limit'=>5000)); while($arr = $dbRes->Fetch()) { $arIds[] = $arr['ELEMENT_ID']; } return $arIds; } public function IsAlreadyLoaded($ID, $type) { $entity = $this->GetImportEntity(); $arFields = array('PROFILE_ID'=>$this->pid, 'ELEMENT_ID'=>$ID, '=TYPE'=>$type); $dbRes = $entity::getList(array('filter'=>$arFields, 'select'=>array('ID'))); if($dbRes->Fetch()) { return true; } return false; } public function OnStartImport() { foreach(GetModuleEvents(static::$moduleId, "OnStartImport", true) as $arEvent) { $bEventRes = ExecuteModuleEventEx($arEvent, array($this->pid)); if($bEventRes===false) return false; } $this->UpdateFields($this->pid, array( 'DATE_START' => new \Bitrix\Main\Type\DateTime(), 'DATE_FINISH' => false )); $this->DeleteImportTmpData(); \Bitrix\Main\Config\Option::set(static::$moduleId, 'IS_ACTIVE_IMPORT', 'Y'); if(\Bitrix\Main\Config\Option::get(static::$moduleId, 'NOTIFY_BEGIN_IMPORT', 'N')=='Y' && (\Bitrix\Main\Config\Option::get(static::$moduleId, 'NOTIFY_MODE', 'NONE')=='ALL' || (\Bitrix\Main\Config\Option::get(static::$moduleId, 'NOTIFY_MODE', 'NONE')=='CRON' && $this->importMode=='CRON'))) { $this->CheckEventOnBeginImport(); $arEventData = array(); $arProfile = $this->GetFieldsByID($this->pid); $arEventData['PROFILE_NAME'] = $arProfile['NAME']; $arEventData['IMPORT_START_DATETIME'] = (is_callable(array($arProfile['DATE_START'], 'toString')) ? $arProfile['DATE_START']->toString() : ''); $arEventData['EMAIL_TO'] = \Bitrix\Main\Config\Option::get(static::$moduleId, 'NOTIFY_EMAIL'); \CEvent::Send('ESOL_XMLIMPORT_START', $this->GetDefaultSiteId(), $arEventData); } return true; } public function OnEndImport($file, $arParams, $arErrors=array(), $arProfParams=array()) { $hash = (isset($arProfParams['FILE_HASH']) && strlen($arProfParams['FILE_HASH']) > 0 ? $arProfParams['FILE_HASH'] : md5_file($file)); $this->UpdateFields($this->pid, array( 'FILE_HASH'=>$hash, 'DATE_FINISH'=>new \Bitrix\Main\Type\DateTime() )); $this->DeleteImportTmpData(); if(!$this->IsActiveProcesses()) { \Bitrix\Main\Config\Option::set(static::$moduleId, 'IS_ACTIVE_IMPORT', 'N'); } $arEventData = array(); if(is_array($arParams)) { foreach($arParams as $k=>$v) { if(!is_array($v)) $arEventData[ToUpper($k)] = $v; } } $arProfile = $this->GetFieldsByID($this->pid); $arEventData['PROFILE_NAME'] = $arProfile['NAME']; $arEventData['IMPORT_START_DATETIME'] = (is_callable(array($arProfile['DATE_START'], 'toString')) ? $arProfile['DATE_START']->toString() : ''); $arEventData['IMPORT_FINISH_DATETIME'] = (is_callable(array($arProfile['DATE_FINISH'], 'toString')) ? $arProfile['DATE_FINISH']->toString() : ''); if($this->importParams['STAT_SAVE']=='Y') { $arSite = $this->GetDefaultSite(); $arEventData['STAT_LINK'] = 'http://'.$arSite['SERVER_NAME'].'/bitrix/admin/'.static::$moduleFilePrefix.'_event_log.php?lang='.LANGUAGE_ID.'&find_profile_id='.($this->pid+1).'&find_exec_id='.$arParams['loggerExecId']; } if(\Bitrix\Main\Config\Option::get(static::$moduleId, 'NOTIFY_END_IMPORT', 'N')=='Y' && (\Bitrix\Main\Config\Option::get(static::$moduleId, 'NOTIFY_MODE', 'NONE')=='ALL' || (\Bitrix\Main\Config\Option::get(static::$moduleId, 'NOTIFY_MODE', 'NONE')=='CRON' && $this->importMode=='CRON'))) { $this->CheckEventOnEndImport(); $arEventData['EMAIL_TO'] = \Bitrix\Main\Config\Option::get(static::$moduleId, 'NOTIFY_EMAIL'); $arEventData['ERRORS'] = implode("\r\n--------\r\n", $arErrors); $arEventData['STAT_BLOCK'] = ''; foreach(array('TOTAL_LINE', 'CORRECT_LINE', 'ERROR_LINE', 'ELEMENT_ADDED_LINE', 'ELEMENT_UPDATED_LINE', 'SECTION_ADDED_LINE', 'SECTION_UPDATED_LINE', 'SKU_ADDED_LINE', 'SKU_UPDATED_LINE', 'KILLED_LINE', 'ZERO_STOCK_LINE', 'OLD_REMOVED_LINE', 'OFFER_KILLED_LINE', 'OFFER_ZERO_STOCK_LINE', 'OFFER_OLD_REMOVED_LINE', 'ERRORS') as $k=>$v) { if($k < 3 || $arEventData[$v] > 0 || strlen($arEventData[$v]) > 1) { $arEventData['STAT_BLOCK'] .= ($v=='ERRORS' ? "\r\n\r\n" : '').Loc::getMessage("ESOL_IX_EVENT_".$v).": ".($v=='ERRORS' ? "\r\n" : '').$arEventData[$v]."\r\n"; } } if(array_key_exists('STAT_LINK', $arEventData)) { $arEventData['STAT_BLOCK'] .= "\r\n".Loc::getMessage("ESOL_IX_EVENT_STAT_LINK").$arEventData['STAT_LINK']; } \CEvent::Send('ESOL_XMLIMPORT_END', $this->GetDefaultSiteId(), $arEventData); } return $arEventData; } public function OnBreakImport($reason='') { if($this->suffix!='highload') { $reason = (strlen(Loc::getMessage("ESOL_IX_BREAK_REASON_".ToUpper($reason))) > 0 ? Loc::getMessage("ESOL_IX_BREAK_REASON_".ToUpper($reason)) : $reason); $arEventData = array('IMPORT_BREAK_REASON'=>$reason); $arProfile = $this->GetFieldsByID($this->pid); $arEventData['PROFILE_NAME'] = $arProfile['NAME']; $arEventData['IMPORT_START_DATETIME'] = (is_callable(array($arProfile['DATE_START'], 'toString')) ? $arProfile['DATE_START']->toString() : ''); if(in_array($reason, array('FILE_NOT_EXISTS'))) $arEventData['IMPORT_START_DATETIME'] = ConvertTimeStamp(false, "FULL"); if(\Bitrix\Main\Config\Option::get(static::$moduleId, 'NOTIFY_BREAK_IMPORT', 'N')=='Y' && (\Bitrix\Main\Config\Option::get(static::$moduleId, 'NOTIFY_MODE', 'NONE')=='ALL' || (\Bitrix\Main\Config\Option::get(static::$moduleId, 'NOTIFY_MODE', 'NONE')=='CRON' && $this->importMode=='CRON'))) { $this->CheckEventOnBreakImport(); $arEventData['EMAIL_TO'] = \Bitrix\Main\Config\Option::get(static::$moduleId, 'NOTIFY_EMAIL'); if(\Bitrix\Main\Config\Option::get(static::$moduleId, 'NOTIFY_WITH_FILE', 'N')=='Y') { \CEvent::Send('ESOL_IMPORT_BREAK', $this->GetDefaultSiteId(), $arEventData, 'Y', '', array($arProfile['DATA_FILE_ID'])); } else { \CEvent::Send('ESOL_IMPORT_BREAK', $this->GetDefaultSiteId(), $arEventData); } } } return $arEventData; } public function DeleteImportTmpData() { $entity = $this->GetImportEntity(); $tblName = $entity->getTableName(); $conn = $entity->getEntity()->getConnection(); $conn->queryExecute('DELETE FROM `'.$tblName.'` WHERE PROFILE_ID='.intval($this->pid)); } public function IsActiveProcesses() { $profileEntity = $this->GetEntity(); $dbRes = $profileEntity::getList(array('select'=>array('ID'), 'order'=>array('SORT'=>'ASC', 'ID'=>'ASC'), 'filter'=>array('>DATE_START'=>\Bitrix\Main\Type\DateTime::createFromTimestamp(time()-30*24*60*60), 'DATE_FINISH'=>false), 'limit'=>1)); while($arProfile = $dbRes->Fetch()) { $tmpfile = $this->tmpdir.$arProfile['ID'].($this->suffix ? '_'.$this->suffix : '').'.txt'; if(file_exists($tmpfile) && (time() - filemtime($tmpfile) < 4*60) && filemtime($tmpfile) > mktime(0, 0, 0, 12, 24, 2015)) { return true; } } return false; } public function GetDefaultSite() { if(!isset($this->defaultSite) || !is_array($this->defaultSite)) { if(!($arSite = \CSite::GetList(($by='sort'), ($order='asc'), array('DEFAULT'=>'Y'))->Fetch())) $arSite = \CSite::GetList(($by='sort'), ($order='asc'), array())->Fetch(); $this->defaultSite = (is_array($arSite) ? $arSite : array()); } return $this->defaultSite; } public function GetDefaultSiteId() { if(!($arSite = \CSite::GetList(($by='sort'), ($order='asc'), array('DEFAULT'=>'Y'))->Fetch())) $arSite = \CSite::GetList(($by='sort'), ($order='asc'), array())->Fetch(); return $arSite['ID']; } public function CheckEventOnBeginImport() { $eventName = 'ESOL_XMLIMPORT_START'; $dbRes = \CEventType::GetList(array('TYPE_ID'=>$eventName)); if(!$dbRes->Fetch()) { $et = new \CEventType(); $et->Add(array( "LID" => "ru", "EVENT_NAME" => $eventName, "NAME" => Loc::getMessage("ESOL_IX_EVENT_IMPORT_START"), "DESCRIPTION" => "#PROFILE_NAME# - ".Loc::getMessage("ESOL_IX_EVENT_PROFILE_NAME")."\r\n". "#IMPORT_START_DATETIME# - ".Loc::getMessage("ESOL_IX_EVENT_TIME_BEGIN") )); } $dbRes = \CEventMessage::GetList(($by='id'), ($order='desc'), array('TYPE_ID'=>$eventName)); if(!$dbRes->Fetch()) { $emess = new \CEventMessage(); $emess->Add(array( 'ACTIVE' => 'Y', 'EVENT_NAME' => $eventName, 'LID' => $this->GetDefaultSiteId(), 'EMAIL_FROM' => '#DEFAULT_EMAIL_FROM#', 'EMAIL_TO' => '#EMAIL_TO#', 'SUBJECT' => '#SITE_NAME#: '.Loc::getMessage("ESOL_IX_EVENT_BEGIN_PROFILE").' "#PROFILE_NAME#"', 'MESSAGE' => Loc::getMessage("ESOL_IX_EVENT_PROFILE_NAME").": #PROFILE_NAME#\r\n". Loc::getMessage("ESOL_IX_EVENT_TIME_BEGIN").": #IMPORT_START_DATETIME#" )); } } public function CheckEventOnEndImport() { $eventName = 'ESOL_XMLIMPORT_END'; $dbRes = \CEventType::GetList(array('TYPE_ID'=>$eventName)); if(!$dbRes->Fetch()) { $et = new \CEventType(); $et->Add(array( "LID" => "ru", "EVENT_NAME" => $eventName, "NAME" => Loc::getMessage("ESOL_IX_EVENT_IMPORT_END"), "DESCRIPTION" => "#PROFILE_NAME# - ".Loc::getMessage("ESOL_IX_EVENT_PROFILE_NAME")."\r\n". "#IMPORT_START_DATETIME# - ".Loc::getMessage("ESOL_IX_EVENT_TIME_BEGIN")."\r\n". "#IMPORT_FINISH_DATETIME# - ".Loc::getMessage("ESOL_IX_EVENT_TIME_END")."\r\n". "#STAT_BLOCK# - ".Loc::getMessage("ESOL_IX_EVENT_STAT_BLOCK")."\r\n". "#TOTAL_LINE# - ".Loc::getMessage("ESOL_IX_EVENT_TOTAL_LINE")."\r\n". "#CORRECT_LINE# - ".Loc::getMessage("ESOL_IX_EVENT_CORRECT_LINE")."\r\n". "#ERROR_LINE# - ".Loc::getMessage("ESOL_IX_EVENT_ERROR_LINE")."\r\n". "#ELEMENT_ADDED_LINE# - ".Loc::getMessage("ESOL_IX_EVENT_ELEMENT_ADDED_LINE")."\r\n". "#ELEMENT_UPDATED_LINE# - ".Loc::getMessage("ESOL_IX_EVENT_ELEMENT_UPDATED_LINE")."\r\n". "#SECTION_ADDED_LINE# - ".Loc::getMessage("ESOL_IX_EVENT_SECTION_ADDED_LINE")."\r\n". "#SECTION_UPDATED_LINE# - ".Loc::getMessage("ESOL_IX_EVENT_SECTION_UPDATED_LINE")."\r\n". "#SKU_ADDED_LINE# - ".Loc::getMessage("ESOL_IX_EVENT_SKU_ADDED_LINE")."\r\n". "#SKU_UPDATED_LINE# - ".Loc::getMessage("ESOL_IX_EVENT_SKU_UPDATED_LINE")."\r\n". "#KILLED_LINE# - ".Loc::getMessage("ESOL_IX_EVENT_KILLED_LINE")."\r\n". "#ZERO_STOCK_LINE# - ".Loc::getMessage("ESOL_IX_EVENT_ZERO_STOCK_LINE")."\r\n". "#OLD_REMOVED_LINE# - ".Loc::getMessage("ESOL_IX_EVENT_OLD_REMOVED_LINE")."\r\n". "#OFFER_KILLED_LINE# - ".Loc::getMessage("ESOL_IX_EVENT_OFFER_KILLED_LINE")."\r\n". "#OFFER_ZERO_STOCK_LINE# - ".Loc::getMessage("ESOL_IX_EVENT_OFFER_ZERO_STOCK_LINE")."\r\n". "#OFFER_OLD_REMOVED_LINE# - ".Loc::getMessage("ESOL_IX_EVENT_OFFER_OLD_REMOVED_LINE") )); } $dbRes = \CEventMessage::GetList(($by='id'), ($order='desc'), array('TYPE_ID'=>$eventName)); if(!$dbRes->Fetch()) { $emess = new \CEventMessage(); $emess->Add(array( 'ACTIVE' => 'Y', 'EVENT_NAME' => $eventName, 'LID' => $this->GetDefaultSiteId(), 'EMAIL_FROM' => '#DEFAULT_EMAIL_FROM#', 'EMAIL_TO' => '#EMAIL_TO#', 'SUBJECT' => '#SITE_NAME#: '.Loc::getMessage("ESOL_IX_EVENT_END_PROFILE").' "#PROFILE_NAME#"', 'MESSAGE' => Loc::getMessage("ESOL_IX_EVENT_PROFILE_NAME").": #PROFILE_NAME#\r\n". Loc::getMessage("ESOL_IX_EVENT_TIME_BEGIN").": #IMPORT_START_DATETIME#\r\n". Loc::getMessage("ESOL_IX_EVENT_TIME_END").": #IMPORT_FINISH_DATETIME#\r\n". "\r\n". Loc::getMessage("ESOL_IX_EVENT_STAT_BLOCK").": \r\n#STAT_BLOCK#" )); } } public function CheckEventOnBreakImport() { $eventName = 'ESOL_IMPORT_BREAK'; $dbRes = \CEventType::GetList(array('TYPE_ID'=>$eventName)); if(!$dbRes->Fetch()) { $et = new \CEventType(); $et->Add(array( "LID" => "ru", "EVENT_NAME" => $eventName, "NAME" => Loc::getMessage("ESOL_IX_EVENT_IMPORT_BREAK"), "DESCRIPTION" => "#PROFILE_NAME# - ".Loc::getMessage("ESOL_IX_EVENT_PROFILE_NAME")."\r\n". "#IMPORT_START_DATETIME# - ".Loc::getMessage("ESOL_IX_EVENT_TIME_BEGIN")."\r\n". "#IMPORT_BREAK_REASON# - ".Loc::getMessage("ESOL_IX_EVENT_IMPORT_BREAK_REASON") )); } $dbRes = \CEventMessage::GetList(($by='id'), ($order='desc'), array('TYPE_ID'=>$eventName)); if(!$dbRes->Fetch()) { $emess = new \CEventMessage(); $emess->Add(array( 'ACTIVE' => 'Y', 'EVENT_NAME' => $eventName, 'LID' => $this->GetDefaultSiteId(), 'EMAIL_FROM' => '#DEFAULT_EMAIL_FROM#', 'EMAIL_TO' => '#EMAIL_TO#', 'SUBJECT' => '#SITE_NAME#: '.Loc::getMessage("ESOL_IX_EVENT_BREAK_PROFILE").' "#PROFILE_NAME#"', 'BODY_TYPE' => 'html', 'MESSAGE' => Loc::getMessage("ESOL_IX_EVENT_PROFILE_NAME").": #PROFILE_NAME#<br>\r\n". Loc::getMessage("ESOL_IX_EVENT_TIME_BEGIN").": #IMPORT_START_DATETIME#<br>\r\n". Loc::getMessage("ESOL_IX_EVENT_IMPORT_BREAK_REASON").": #IMPORT_BREAK_REASON#" )); } } public function OutputBackup() { global $APPLICATION; $APPLICATION->RestartBuffer(); $fileName = 'profiles_'.date('Y_m_d_H_i_s'); $tempPath = \CFile::GetTempName('', bx_basename($fileName.'.zip')); $dir = rtrim(\Bitrix\Main\IO\Path::getDirectory($tempPath), '/').'/'.$fileName; \Bitrix\Main\IO\Directory::createDirectory($dir); $arFiles = array( 'config' => $dir.'/config.txt', 'data' => $dir.'/data.txt' ); file_put_contents($arFiles['config'], base64_encode(serialize( array( 'domain' => $_SERVER['HTTP_HOST'], 'encoding' => \Bitrix\EsolImportxml\Utils::getSiteEncoding() ) ))); $handle = fopen($arFiles['data'], 'a'); $profileEntity = $this->GetEntity(); $dbRes = $profileEntity::getList(array('order'=>array('ID'=>'ASC'), 'select'=>array('ID', 'ACTIVE', 'NAME', 'PARAMS', 'SORT'))); while($arProfile = $dbRes->Fetch()) { /*Save iblock data*/ if(Loader::includeModule('iblock') && class_exists('\Bitrix\Iblock\PropertyTable') && isset($arProfile['PARAMS']) && strlen($arProfile['PARAMS']) > 0 && ($arProfileParams = self::DecodeProfileParams($arProfile['PARAMS'])) && is_array($arProfileParams)) { $iblockId = $arProfileParams['SETTINGS_DEFAULT']['IBLOCK_ID']; $arPropIds = array(); if(isset($arProfileParams['SETTINGS']['FIELDS']) && is_array($arProfileParams['SETTINGS']['FIELDS'])) { foreach($arProfileParams['SETTINGS']['FIELDS'] as $k=>$v) { if(preg_match('/IP_PROP(\d+)/', $v, $m)) $arPropIds[$m[1]] = $m[1]; } } if(isset($arProfileParams['SETTINGS']['PROPERTY_MAP']) && strlen($arProfileParams['SETTINGS']['PROPERTY_MAP']) > 0) { $arMap = unserialize(base64_decode($arProfileParams['SETTINGS']['PROPERTY_MAP'])); if(is_array($arMap) && isset($arMap['MAP']) && is_array($arMap['MAP'])) { foreach($arMap['MAP'] as $k=>$v) { if(preg_match('/IP_PROP(\d+)/', $v['ID'], $m)) $arPropIds[$m[1]] = $m[1]; } } } if(count($arPropIds) > 0) { $arProps = array($iblockId=>array()); $dbRes2 = \Bitrix\Iblock\PropertyTable::getList(array('filter' => array('=IBLOCK_ID'=>$iblockId, 'ID'=>$arPropIds), 'select' => array('ID', 'IBLOCK_ID', 'CODE', 'NAME'))); while($arr = $dbRes2->Fetch()) { $arProps[$arr['IBLOCK_ID']][$arr['ID']] = array('CODE'=>$arr['CODE'], 'NAME'=>$arr['NAME']); } } $arProfileParams['OLD_IBLOCK_DATA'] = array('PROPS'=>$arProps); $arProfile['PARAMS'] = self::EncodeProfileParams($arProfileParams); } /*/Save iblock data*/ foreach($arProfile as $k=>$v) { $arProfile[$k] = base64_encode($v); } fwrite($handle, base64_encode(serialize($arProfile))."\r\n"); } fclose($handle); $zipObj = \CBXArchive::GetArchive($tempPath, 'ZIP'); $zipObj->SetOptions(array( "COMPRESS" =>true, "ADD_PATH" => false, "REMOVE_PATH" => $dir.'/', )); $zipObj->Pack($dir.'/'); foreach($arFiles as $file) unlink($file); rmdir($dir); header('Content-type: application/zip'); header('Content-Transfer-Encoding: Binary'); header('Content-length: '.filesize($tempPath)); header('Content-disposition: attachment; filename="'.basename($tempPath).'"'); readfile($tempPath); die(); } public function RestoreBackup($arPFile, $arParams) { if(!isset($arPFile) || !is_array($arPFile) || $arPFile['error'] > 0 || $arPFile['size'] < 1) { return array('TYPE'=>'ERROR', 'MESSAGE'=>Loc::getMessage("ESOL_IX_RESTORE_NOT_LOAD_FILE")); } $filename = $arPFile['name']; if(ToLower(\Bitrix\EsolImportxml\Utils::GetFileExtension($filename))!=='zip') { return array('TYPE'=>'ERROR', 'MESSAGE'=>Loc::getMessage("ESOL_IX_RESTORE_FILE_NOT_VALID")); } $tempPath = \CFile::GetTempName('', bx_basename($filename)); $subdir = current(explode('.', $filename)); if(strlen($subdir)==0) $subdir = 'backup'; $dir = rtrim(\Bitrix\Main\IO\Path::getDirectory($tempPath), '/').'/'.$subdir; \Bitrix\Main\IO\Directory::createDirectory($dir); $zipObj = \CBXArchive::GetArchive($arPFile['tmp_name'], 'ZIP'); $zipObj->Unpack($dir.'/'); $arFiles = array( 'config' => $dir.'/config.txt', 'data' => $dir.'/data.txt' ); if(!file_exists($arFiles['config']) || !file_exists($arFiles['data'])) { foreach($arFiles as $file) unlink($file); rmdir($dir); return array('TYPE'=>'ERROR', 'MESSAGE'=>Loc::getMessage("ESOL_IX_RESTORE_FILE_NOT_VALID")); } $profileEntity = $this->GetEntity(); $encoding = \Bitrix\EsolImportxml\Utils::getSiteEncoding(); if($arParams['RESTORE_TYPE']=='REPLACE') { $dbRes = $profileEntity::getList(); while($arProfile = $dbRes->Fetch()) { $profileEntity::delete($arProfile['ID']); } } $arConfig = unserialize(base64_decode(file_get_contents($arFiles['config']))); $handle = fopen($arFiles['data'], "r"); while(!feof($handle)) { $buffer = trim(fgets($handle, 16777216)); if(strlen($buffer) == 0) continue; $arProfile = unserialize(base64_decode($buffer)); if(!is_array($arProfile)) continue; foreach($arProfile as $k=>$v) { $v = base64_decode($v); if($encoding != $arConfig['encoding']) { if($k=='PARAMS') { $v = self::DecodeProfileParams($v); $v = \Bitrix\Main\Text\Encoding::convertEncoding($v, $arConfig['encoding'], $encoding); $v = self::EncodeProfileParams($v); } else { $v = \Bitrix\Main\Text\Encoding::convertEncoding($v, $arConfig['encoding'], $encoding); } } $arProfile[$k] = $v; } if($arParams['RESTORE_TYPE']=='ADD') unset($arProfile['ID']); $dbRes = $profileEntity::add($arProfile); /*if(!$dbRes->isSuccess()) { $error = ''; if($dbRes->getErrors()) { foreach($dbRes->getErrors() as $errorObj) { $error .= $errorObj->getMessage().'. '; } $APPLICATION->throwException($error); } } else { $ID = $dbRes->getId(); }*/ } fclose($handle); foreach($arFiles as $file) unlink($file); rmdir($dir); return array('TYPE'=>'SUCCESS', 'MESSAGE'=>Loc::getMessage("ESOL_IX_RESTORE_SUCCESS")); } }