Current Path : /var/www/www-root/data/www/monolith-realty.ru/bitrix/modules/iblock/admin/ |
Current File : /var/www/www-root/data/www/monolith-realty.ru/bitrix/modules/iblock/admin/iblock_convert.php |
<?php /** @global CMain $APPLICATION */ /** @global CDatabase $DB */ use Bitrix\Main\Context; use Bitrix\Main\Localization\Loc; use Bitrix\Iblock\IblockTable; require_once $_SERVER['DOCUMENT_ROOT'].'/bitrix/modules/main/include/prolog_admin_before.php'; CJSCore::Init(array('ajax')); CModule::IncludeModule('iblock'); require_once $_SERVER['DOCUMENT_ROOT'].'/bitrix/modules/iblock/prolog.php'; $request = Context::getCurrent()->getRequest(); $IBLOCK_ID = (int)$request->get('IBLOCK_ID'); $WAY = (int)$request->get('WAY'); $STEP = (int)$request->get('STEP'); $INTERVAL = 20;//sec TODO make setting? $isSidePanel = $request->get('IFRAME') === 'Y'; if ($STEP == 0) { $_SESSION["BX_IBLOCK_CONV"] = false; } elseif (is_array($_SESSION["BX_IBLOCK_CONV"] ?? null)) { $ar = array( "DONE" => intval($_SESSION["BX_IBLOCK_CONV"]["DONE"] ?? null), "TODO" => intval($_SESSION["BX_IBLOCK_CONV"]["TODO"] ?? null), "arMultiple" => array(), "arSingle" => array(), "arNumber" => array(), ); if(is_array($_SESSION["BX_IBLOCK_CONV"]["arMultiple"])) { foreach($_SESSION["BX_IBLOCK_CONV"]["arMultiple"] as $id) { $id = intval($id); $ar["arMultiple"][$id] = $id; } } if(is_array($_SESSION["BX_IBLOCK_CONV"]["arSingle"])) { foreach($_SESSION["BX_IBLOCK_CONV"]["arSingle"] as $id) { $id = intval($id); $ar["arSingle"][$id] = $id; } } if(is_array($_SESSION["BX_IBLOCK_CONV"]["arNumber"])) { foreach($_SESSION["BX_IBLOCK_CONV"]["arNumber"] as $id) { $id = intval($id); $ar["arNumber"][$id] = $id; } } $_SESSION["BX_IBLOCK_CONV"] = $ar; } else { $_SESSION["BX_IBLOCK_CONV"] = false; } $arErrors = array(); $arMessages = array(); $APPLICATION->SetTitle(Loc::getMessage("IBCONV_TITLE")); $sTableID = "tbl_iblock_convert"; $lAdmin = new CAdminList($sTableID); $lAdmin->BeginCustomContent(); $arIBlock = false; if(!CIBlockRights::UserHasRightTo($IBLOCK_ID, $IBLOCK_ID, "iblock_edit") || (!check_bitrix_sessid() && $STEP > 0)) { $arErrors[]=Loc::getMessage("IBCONV_PERMISSION"); } else { $rsIBlock = CIBlock::GetList(array(), array("ID" => $IBLOCK_ID, "CHECK_PERMISSIONS" => "N")); if($arIBlock = $rsIBlock->Fetch()) { if ($arIBlock["VERSION"] == IblockTable::PROPERTY_STORAGE_COMMON) { if($STEP!=0 && $WAY!=12) $arErrors[]=Loc::getMessage("IBCONV_WRONG_CONVERSION"); elseif($STEP==1) $STEP = 2; elseif($STEP==2) $STEP = FirstStep12($arIBlock); elseif($STEP==3) $STEP = NextStep12($arIBlock); elseif($STEP==4) $STEP = 5; elseif($STEP==5) $STEP = LastStep12($arIBlock); } elseif($arIBlock["VERSION"] == IblockTable::PROPERTY_STORAGE_SEPARATE) { if($STEP!=0 && $WAY!=21) $arErrors[]=Loc::getMessage("IBCONV_WRONG_CONVERSION"); elseif($STEP==1) $STEP = 2; elseif($STEP==2) $STEP = FirstStep21($arIBlock); elseif($STEP==3) $STEP = NextStep21($arIBlock); elseif($STEP==4) $STEP = 5; elseif($STEP==5) $STEP = LastStep21($arIBlock); } else { $arErrors[]=Loc::getMessage("IBCONV_WRONG_VERSION"); } } else { $arErrors[]=Loc::getMessage("IBCONV_WRONG_IBLOCK"); } } foreach($arErrors as $strError) CAdminMessage::ShowMessage($strError); foreach($arMessages as $strMessage) CAdminMessage::ShowMessage(array("MESSAGE"=>$strMessage,"TYPE"=>"OK")); if (empty($arErrors)): if ($STEP == 0):?> <p><span class="required"><?=Loc::getMessage("IBCONV_ATTENTION")?></span> <?=Loc::getMessage("IBCONV_WARNING_MESSAGE",array("#IBLOCK_NAME#"=>htmlspecialcharsbx($arIBlock["NAME"])))?> <input type="button" name="START" value="<?=Loc::getMessage("IBCONV_MOVE")?>" onclick="DoNext(<?= ($arIBlock["VERSION"] == IblockTable::PROPERTY_STORAGE_SEPARATE ? 21 : 12); ?>,1)" > <?php elseif ($STEP >= 1 && $STEP <= 5): if ($WAY == 12): ?> <p><ul> <li><?=$STEP==2?'<b>':''?><?=Loc::getMessage("IBCONV_CREATE_TABLE")?><?=$STEP==2?'</b>':''?></li> <?php if (is_array($_SESSION["BX_IBLOCK_CONV"] ?? null)): ?> <li><?=$STEP==3?'<b>':''?><?=Loc::getMessage("IBCONV_PROGRESS",array("#DONE#"=>$_SESSION["BX_IBLOCK_CONV"]["DONE"],"#TODO#"=>$_SESSION["BX_IBLOCK_CONV"]["TODO"]))?><?=$STEP==3?'</b>':''?></li> <?php else: ?> <li><?=$STEP==3?'<b>':''?><?=Loc::getMessage("IBCONV_INPROGRESS")?><?=$STEP==3?'</b>':''?></li> <?php endif; ?> <li><?=$STEP==5?'<b>':''?><?=Loc::getMessage("IBCONV_FINALIZE")?><?=$STEP==5?'</b>':''?></li> </ul></p> <?php else: ?> <p><ul> <li><?= ($STEP == 2 ? '<b>' : ''); ?><?= Loc::getMessage("IBCONV_PREPARE"); ?><?= ($STEP == 2 ? '</b>' : ''); ?></li> <?php if (is_array($_SESSION["BX_IBLOCK_CONV"] ?? null)): ?> <li><?= ($STEP == 3 ? '<b>' : ''); ?><?= Loc::getMessage("IBCONV_PROGRESS",array("#DONE#"=>$_SESSION["BX_IBLOCK_CONV"]["DONE"],"#TODO#"=>$_SESSION["BX_IBLOCK_CONV"]["TODO"]))?><?=$STEP==3?'</b>':''?></li> <?php else: ?> <li><?=$STEP==3?'<b>':''?><?=Loc::getMessage("IBCONV_INPROGRESS")?><?=$STEP==3?'</b>':''?></li> <?php endif; ?> <li><?=$STEP==5?'<b>':''?><?=Loc::getMessage("IBCONV_FINALIZE2")?><?=$STEP==5?'</b>':''?></li> </ul></p> <?php endif; ?> <script>setTimeout('DoNext(<?=$WAY?>,<?=$STEP?>)', 500);</script> <?php else: ?> <p><?=Loc::getMessage("IBCONV_FINISHED")?></p> <?php if ($isSidePanel): ?> <p onclick="top.BX.onCustomEvent('SidePanel:close');"><a href="javascript:void(0)"><?=Loc::getMessage("IBCONV_FINISHED_HREF")?></a></p> <?php else: ?> <p><a href="iblock_edit.php?ID=<?=$arIBlock["ID"]?>&type=<?=$arIBlock["IBLOCK_TYPE_ID"]?>&lang=<?=LANG?>&admin=Y"><?=Loc::getMessage("IBCONV_FINISHED_HREF")?></a></p> <?php endif; endif; endif; $lAdmin->EndCustomContent(); if($STEP==0) require($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/prolog_admin_after.php"); else require_once($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/prolog_admin_js.php"); ?> <script> function DoNext(way, step){ var queryString='lang=<?= LANGUAGE_ID; ?>'; queryString+='&IBLOCK_ID=<?= $IBLOCK_ID; ?>'; queryString+='&WAY='+way; queryString+='&STEP='+step; queryString+='&<?= bitrix_sessid_get(); ?>'; <?php if ($isSidePanel): ?> queryString+='&IFRAME=Y';<?php endif; ?> BX.showWait(); BX.ajax.post('iblock_convert.php?'+queryString, null, function(result) { BX('tbl_iblock_convert_result_div').innerHTML = result; BX.closeWait(); }); } </script> <?php function FirstStep12($arIBlock): int { //global $DB, $_SESSION, $arErrors, $arMessages, $INTERVAL; global $DB, $_SESSION, $arErrors; $arIBlock["ID"] = (int)$arIBlock["ID"]; $obIBlock = new CIBlock; $LAST_CONV_ELEMENT = (int)($arIBlock["LAST_CONV_ELEMENT"] ?? 0); if ($LAST_CONV_ELEMENT == 0) { $strSql = " SELECT COUNT(*) CNT FROM b_iblock_property WHERE IBLOCK_ID = ".$arIBlock["ID"]." "; $rs = $DB->Query($strSql); if($ar = $rs->Fetch()) { if($ar["CNT"] > 50) { $arErrors[] = Loc::getMessage("IBCONV_TOO_MANY_PROPERTIES", array("#NUM#" => 50)); return 3; } } $bOK = $obIBlock->_Add($arIBlock["ID"]); $DB->Query("UPDATE b_iblock SET LAST_CONV_ELEMENT = -1 WHERE ID = ".$arIBlock["ID"]); } else { $bOK = true; } if($bOK) { $obIBlockProperty = new CIBlockProperty; $arMultiple = array(); $arSingle = array(); $arNumber = array(); $strSql = " SELECT ID ,MULTIPLE ,PROPERTY_TYPE ,IBLOCK_ID ,WITH_DESCRIPTION FROM b_iblock_property WHERE IBLOCK_ID=".$arIBlock["ID"]." "; $rs = $DB->Query($strSql); while($ar = $rs->Fetch()) { $id = intval($ar["ID"]); if($ar["MULTIPLE"]=="Y") $arMultiple[$id] = $id; else $arSingle[$id] = $id; if($ar["PROPERTY_TYPE"]=="N") $arNumber[$id] = $id; if($LAST_CONV_ELEMENT == 0) $obIBlockProperty->_Add($id, $ar); } $strSql = " SELECT COUNT('x') AS CNT FROM b_iblock_element WHERE IBLOCK_ID=".$arIBlock["ID"]." AND ID > ".$LAST_CONV_ELEMENT." "; $rs = $DB->Query($strSql); $ar = $rs->Fetch(); if ($ar && $ar["CNT"]>0) { $_SESSION["BX_IBLOCK_CONV"] = [ "DONE" => 0, "TODO" => $ar["CNT"], "arMultiple" => $arMultiple, "arSingle" => $arSingle, "arNumber" => $arNumber, ]; } else { return 4;//nothing todo } } else { $arErrors[] = Loc::getMessage("IBCONV_TABLE_CREATION_ERROR"); } return 3; } function NextStep12($arIBlock): int { //global $DB, $_SESSION, $arErrors, $arMessages, $INTERVAL; global $DB, $_SESSION, $INTERVAL; $arIBlock["ID"] = (int)$arIBlock["ID"]; $LAST_CONV_ELEMENT = (int)($arIBlock["LAST_CONV_ELEMENT"] ?? 0); $strSql = " SELECT ID FROM b_iblock_element WHERE IBLOCK_ID = ".$arIBlock["ID"]." AND ID>".$LAST_CONV_ELEMENT." ORDER BY ID "; $rsID = $DB->Query($strSql); $t = microtime(true); $i = 0; while($arID = $rsID->Fetch()) { $ELEMENT_ID=$arID["ID"]; /** @noinspection SqlResolve */ $strSql = " INSERT INTO b_iblock_element_prop_s".$arIBlock["ID"]." (IBLOCK_ELEMENT_ID) VALUES (".$ELEMENT_ID.") "; $rs = $DB->Query($strSql, true); if(!$rs) continue; if (!empty($_SESSION["BX_IBLOCK_CONV"]["arMultiple"])) { $strSql = " INSERT INTO b_iblock_element_prop_m".$arIBlock["ID"]." (IBLOCK_ELEMENT_ID,IBLOCK_PROPERTY_ID,VALUE,VALUE_ENUM,VALUE_NUM,DESCRIPTION) SELECT IBLOCK_ELEMENT_ID,IBLOCK_PROPERTY_ID,VALUE,VALUE_ENUM,VALUE_NUM,DESCRIPTION FROM b_iblock_element_property WHERE IBLOCK_ELEMENT_ID = ".$ELEMENT_ID." AND IBLOCK_PROPERTY_ID IN (".implode(", ", $_SESSION["BX_IBLOCK_CONV"]["arMultiple"]).") "; $DB->Query($strSql); } if (!empty($_SESSION["BX_IBLOCK_CONV"]["arSingle"])) { $arFields=array(); $strSql = " SELECT * FROM b_iblock_element_property WHERE IBLOCK_ELEMENT_ID = ".$ELEMENT_ID." AND IBLOCK_PROPERTY_ID IN (".implode(", ", $_SESSION["BX_IBLOCK_CONV"]["arSingle"]).") "; $rs = $DB->Query($strSql); while($ar = $rs->Fetch()) { $arFields["PROPERTY_".$ar["IBLOCK_PROPERTY_ID"]] = $ar["VALUE"]; $arFields["DESCRIPTION_".$ar["IBLOCK_PROPERTY_ID"]] = $ar["DESCRIPTION"] ?? null; } if(count($arFields)>0) { $strUpdate = $DB->PrepareUpdateBind("b_iblock_element_prop_s".$arIBlock["ID"], $arFields, "iblock", false, $arBinds); if($strUpdate <> '') { $strSql = "UPDATE b_iblock_element_prop_s".$arIBlock["ID"]." SET ".$strUpdate." WHERE IBLOCK_ELEMENT_ID=".$ELEMENT_ID; $DB->QueryBind($strSql, $arBinds); } } } $strSql = " DELETE FROM b_iblock_element_property WHERE IBLOCK_ELEMENT_ID = ".$ELEMENT_ID." "; $DB->Query($strSql); $DB->Query("UPDATE b_iblock SET LAST_CONV_ELEMENT = ".$ELEMENT_ID." WHERE ID = ".$arIBlock["ID"]); $i++; if ((microtime(true) - $t) > $INTERVAL) { break; } } $_SESSION["BX_IBLOCK_CONV"]["DONE"]+=$i; if($_SESSION["BX_IBLOCK_CONV"]["TODO"]<$_SESSION["BX_IBLOCK_CONV"]["DONE"]) $_SESSION["BX_IBLOCK_CONV"]["TODO"]=$_SESSION["BX_IBLOCK_CONV"]["DONE"]; //$_SESSION["BX_IBLOCK_CONV"]["STAT"][]=$i;$arMessages[]=implode(', ',$_SESSION["BX_IBLOCK_CONV"]["STAT"]); if($arID) { return 3; } else { return 4; } } function LastStep12($arIBlock): int { //global $DB,$_SESSION,$arErrors,$arMessages,$INTERVAL; global $DB; $arIBlock['ID'] = (int)$arIBlock['ID']; $DB->Query('UPDATE b_iblock_property SET VERSION=2 WHERE IBLOCK_ID = '.$arIBlock['ID']); $DB->Query('UPDATE b_iblock SET VERSION=2,LAST_CONV_ELEMENT = 0 WHERE ID = '.$arIBlock['ID']); CIBlock::CleanCache($arIBlock['ID']); return 6; } function FirstStep21($arIBlock): int { //global $DB,$_SESSION,$arErrors,$arMessages,$INTERVAL; global $DB,$_SESSION; $arIBlock["ID"] = (int)$arIBlock["ID"]; $arMultiple = array(); $arSingle = array(); $arNumber = array(); $strSql = " SELECT ID ,MULTIPLE ,PROPERTY_TYPE ,IBLOCK_ID FROM b_iblock_property WHERE IBLOCK_ID=".$arIBlock["ID"]." "; $rs = $DB->Query($strSql); while($ar = $rs->Fetch()) { $id = intval($ar["ID"]); if($ar["MULTIPLE"]=="Y") $arMultiple[$id] = $id; else $arSingle[$id] = $id; if($ar["PROPERTY_TYPE"]=="N") $arNumber[$id] = $id; } $strSql = " SELECT COUNT('x') AS CNT FROM b_iblock_element_prop_s".$arIBlock["ID"]." "; $rs = $DB->Query($strSql); $ar = $rs->Fetch(); if($ar && $ar["CNT"]>0) { $_SESSION["BX_IBLOCK_CONV"] = [ "DONE" => 0, "TODO" => $ar["CNT"], "arMultiple" => $arMultiple, "arSingle" => $arSingle, "arNumber" => $arNumber, ]; return 3; } else { return 4;//nothing todo } } function NextStep21($arIBlock): int { //global $DB,$_SESSION,$arErrors,$arMessages,$INTERVAL; global $DB, $_SESSION, $INTERVAL; $arIBlock["ID"] = (int)$arIBlock["ID"]; $strSql = " SELECT * FROM b_iblock_element_prop_s".$arIBlock["ID"]." "; $rsElement = $DB->Query($strSql); $t = microtime(true); $i = 0; while($arElement = $rsElement->Fetch()) { $ELEMENT_ID=$arElement["IBLOCK_ELEMENT_ID"]; foreach($arElement as $key=>$value) { if(mb_substr($key, 0, 9) == "PROPERTY_" && $value <> '') { $ID = intval(mb_substr($key, 9));//TODO make conversion and check forsql and bind!!!! if($ID > 0 && array_key_exists($ID, $_SESSION["BX_IBLOCK_CONV"]["arSingle"])) { $arFields = array( "IBLOCK_ELEMENT_ID"=>$ELEMENT_ID, "IBLOCK_PROPERTY_ID"=>$ID, "VALUE"=>$value, "~VALUE_NUM"=>CIBlock::roundDB($value), "~VALUE_ENUM"=>intval($value), "DESCRIPTION"=> ($arElement["DESCRIPTION_".$ID] ?? null), ); $arInsert = $DB->PrepareInsert("b_iblock_element_property", $arFields); $DB->QueryBind( "INSERT INTO b_iblock_element_property (".$arInsert[0].")VALUES(".$arInsert[1].")", [ "DESCRIPTION"=>$arElement["DESCRIPTION_".$ID] ?? null, ] ); } } } $strSql = " INSERT INTO b_iblock_element_property (IBLOCK_ELEMENT_ID,IBLOCK_PROPERTY_ID,VALUE,VALUE_ENUM,VALUE_NUM,DESCRIPTION) SELECT IBLOCK_ELEMENT_ID,IBLOCK_PROPERTY_ID,VALUE,VALUE_ENUM,VALUE_NUM,DESCRIPTION FROM b_iblock_element_prop_m".$arIBlock["ID"]." WHERE IBLOCK_ELEMENT_ID = ".$ELEMENT_ID." "; $DB->Query($strSql); $strSql = " DELETE FROM b_iblock_element_prop_m".$arIBlock["ID"]." WHERE IBLOCK_ELEMENT_ID = ".$ELEMENT_ID." "; $DB->Query($strSql); $strSql = " DELETE FROM b_iblock_element_prop_s".$arIBlock["ID"]." WHERE IBLOCK_ELEMENT_ID = ".$ELEMENT_ID." "; $DB->Query($strSql); $DB->Query("UPDATE b_iblock SET LAST_CONV_ELEMENT = ".$ELEMENT_ID." WHERE ID = ".$arIBlock["ID"]); $i++; if ((microtime(true) - $t) > $INTERVAL) { break; } } $_SESSION["BX_IBLOCK_CONV"]["DONE"]+=$i; if($_SESSION["BX_IBLOCK_CONV"]["TODO"]<$_SESSION["BX_IBLOCK_CONV"]["DONE"]) $_SESSION["BX_IBLOCK_CONV"]["TODO"]=$_SESSION["BX_IBLOCK_CONV"]["DONE"]; //$_SESSION["BX_IBLOCK_CONV"]["STAT"][]=$i;$arMessages[]=implode(', ',$_SESSION["BX_IBLOCK_CONV"]["STAT"]); if($arElement) return 3; else return 4; } function LastStep21($arIBlock): int { //global $DB,$_SESSION,$arErrors,$arMessages,$INTERVAL; global $DB; $arIBlock["ID"] = (int)$arIBlock["ID"]; $DB->Query("UPDATE b_iblock_property SET VERSION= 1 WHERE IBLOCK_ID = ".$arIBlock["ID"]); $DB->Query("UPDATE b_iblock SET VERSION=1,LAST_CONV_ELEMENT = 0 WHERE ID = ".$arIBlock["ID"]); CIBlock::CleanCache($arIBlock["ID"]); $DB->DDL("DROP TABLE b_iblock_element_prop_s".$arIBlock["ID"]); $DB->DDL("DROP TABLE b_iblock_element_prop_m".$arIBlock["ID"]); $DB->DDL("DROP SEQUENCE sq_b_iblock_element_prop_m".$arIBlock["ID"], true); return 6; } $lAdmin->DisplayList(); if ($STEP == 0) { require $_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/include/epilog_admin.php'; } else { require $_SERVER['DOCUMENT_ROOT'] . BX_ROOT . '/modules/main/include/epilog_admin_js.php'; }