Скрипт Вставки в тексты

<?php require($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/prolog_before.php"); CModule::IncludeModule("iblock"); // Подключение к базе данных global $DB; // Обработка AJAX запросов if ($_POST['action'] == 'get_sections_count') { $iblocks = $_POST['iblocks']; $level = intval($_POST['level']); $totalSections = 0; foreach ($iblocks as $iblockId) { $filter = array( 'IBLOCK_ID' => $iblockId, 'DEPTH_LEVEL' => $level, 'ACTIVE' => 'Y' ); $sections = CIBlockSection::GetList(array(), $filter, false, array('ID')); while ($section = $sections->Fetch()) { $totalSections++; } } echo json_encode(array('total' => $totalSections)); die(); } if ($_POST['action'] == 'check_properties') { $iblocks = $_POST['iblocks']; $result = array(); foreach ($iblocks as $iblockId) { $iblock = CIBlock::GetByID($iblockId)->Fetch(); // Проверяем существование таблицы и полей напрямую в БД $tableName = 'b_uts_iblock_' . $iblockId . '_section'; // Проверяем существование таблицы $tableExists = false; $hasUpProperty = false; $hasDownProperty = false; $checkTableQuery = "SHOW TABLES LIKE '" . $tableName . "'"; $tableResult = $DB->Query($checkTableQuery); if ($tableResult->Fetch()) { $tableExists = true; // Проверяем существование полей $checkColumnsQuery = "SHOW COLUMNS FROM `" . $tableName . "`"; $columnsResult = $DB->Query($checkColumnsQuery); while ($column = $columnsResult->Fetch()) { if ($column['Field'] == 'UF_UP_IMAGES_BLOCK') { $hasUpProperty = true; } if ($column['Field'] == 'UF_DOWN_IMAGES_BLOCK') { $hasDownProperty = true; } } } $result[] = array( 'id' => $iblockId, 'name' => $iblock['NAME'], 'table_exists' => $tableExists, 'table_name' => $tableName, 'has_up_property' => $hasUpProperty, 'has_down_property' => $hasDownProperty ); } echo json_encode($result); die(); } if ($_POST['action'] == 'process_sections') { $iblocks = $_POST['iblocks']; $level = intval($_POST['level']); $step = intval($_POST['step']); $offset = intval($_POST['offset']); $upProperties = $_POST['up_properties']; $downProperties = $_POST['down_properties']; $overwriteUp = $_POST['overwrite_up'] == '1'; $overwriteDown = $_POST['overwrite_down'] == '1'; $processed = 0; $currentSection = ''; $currentIblock = ''; $currentOffset = intval($_POST['offset']); $globalOffset = 0; foreach ($iblocks as $iblockId) { $iblock = CIBlock::GetByID($iblockId)->Fetch(); $currentIblock = $iblock['NAME'] . " (ID: $iblockId)"; $tableName = 'b_uts_iblock_' . $iblockId . '_section'; // Проверяем существование таблицы $checkTableQuery = "SHOW TABLES LIKE '" . $tableName . "'"; $tableResult = $DB->Query($checkTableQuery); if (!$tableResult->Fetch()) { continue; // Пропускаем если таблицы нет } $filter = array( 'IBLOCK_ID' => $iblockId, 'DEPTH_LEVEL' => $level, 'ACTIVE' => 'Y' ); $sections = CIBlockSection::GetList(array('ID' => 'ASC'), $filter, false, array('ID', 'NAME')); $sectionCount = 0; while ($section = $sections->Fetch()) { if ($globalOffset < $currentOffset) { $globalOffset++; continue; } if ($processed >= $step) { break 2; } $sectionId = $section['ID']; $currentSection = $section['NAME'] . " (ID: {$sectionId})"; // Получаем данные из таблицы пользовательских свойств $selectQuery = "SELECT * FROM `" . $tableName . "` WHERE VALUE_ID = " . intval($sectionId); $sectResult = $DB->Query($selectQuery); $sectData = $sectResult->Fetch(); if (!$sectData) { // Если записи нет, создаем её $insertQuery = "INSERT INTO `" . $tableName . "` (VALUE_ID) VALUES (" . intval($sectionId) . ")"; $DB->Query($insertQuery); $sectData = array('VALUE_ID' => $sectionId); } $updateFields = array(); // Обработка UF_UP_IMAGES_BLOCK if (!empty($upProperties) && ($overwriteUp || empty($sectData['UF_UP_IMAGES_BLOCK']))) { $upContent = ''; foreach ($upProperties as $prop) { if (!empty($sectData[$prop])) { $upContent .= $sectData[$prop]; } } if (!empty($upContent) || $overwriteUp) { $updateFields['UF_UP_IMAGES_BLOCK'] = "'" . $DB->ForSql($upContent) . "'"; } } // Обработка UF_DOWN_IMAGES_BLOCK if (!empty($downProperties) && ($overwriteDown || empty($sectData['UF_DOWN_IMAGES_BLOCK']))) { $downContent = ''; foreach ($downProperties as $prop) { if (!empty($sectData[$prop])) { $downContent .= $sectData[$prop]; } } if (!empty($downContent) || $overwriteDown) { $updateFields['UF_DOWN_IMAGES_BLOCK'] = "'" . $DB->ForSql($downContent) . "'"; } } // Обновляем данные в БД if (!empty($updateFields)) { $updateParts = array(); foreach ($updateFields as $field => $value) { $updateParts[] = "`" . $field . "` = " . $value; } $updateQuery = "UPDATE `" . $tableName . "` SET " . implode(', ', $updateParts) . " WHERE VALUE_ID = " . intval($sectionId); $DB->Query($updateQuery); } $processed++; $globalOffset++; } if ($processed >= $step) { break; } } echo json_encode(array( 'processed' => $processed, 'current_section' => $currentSection, 'current_iblock' => $currentIblock, 'new_offset' => $currentOffset + $processed )); die(); } // Получение списка инфоблоков $iblocks = array(); $res = CIBlock::GetList(array('SORT' => 'ASC', 'NAME' => 'ASC'), array('ACTIVE' => 'Y')); while ($iblock = $res->Fetch()) { $iblocks[] = $iblock; } // Свойства BLOCKCODE $blockCodeProperties = array( 'UF_IMAGE1_BLOCKCODE' => 'IMAGE1_BLOCKCODE', 'UF_IMAGE2_BLOCKCODE' => 'IMAGE2_BLOCKCODE', 'UF_IMAGE3_BLOCKCODE' => 'IMAGE3_BLOCKCODE', 'UF_IMAGE4_BLOCKCODE' => 'IMAGE4_BLOCKCODE', 'UF_IMAGE5_BLOCKCODE' => 'IMAGE5_BLOCKCODE', 'UF_IMAGE6_BLOCKCODE' => 'IMAGE6_BLOCKCODE', 'UF_IMAGE7_BLOCKCODE' => 'IMAGE7_BLOCKCODE' ); ?> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Формирование блоков картинок для разделов</title> <style> body { font-family: arial, sans-serif; margin: 20px; background-color: #f9f9f9; } .container { max-width: 800px; margin: 0 auto; background: white; padding: 20px; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); } h1 { color: #1a73e8; margin-bottom: 30px; } .form-group { margin-bottom: 20px; } label { display: block; margin-bottom: 5px; font-weight: bold; } input[type="text"], input[type="number"], select { width: 100%; padding: 8px 12px; border: 1px solid #dadce0; border-radius: 4px; font-size: 14px; box-sizing: border-box; } input[type="text"]:focus, input[type="number"]:focus, select:focus { outline: none; border-color: #1a73e8; box-shadow: 0 0 0 2px rgba(26,115,232,0.2); } .multi-select { width: 100%; height: 150px; padding: 8px; border: 1px solid #dadce0; border-radius: 4px; font-size: 14px; box-sizing: border-box; resize: vertical; } .multi-select:focus { outline: none; border-color: #1a73e8; box-shadow: 0 0 0 2px rgba(26,115,232,0.2); } .multi-select option { padding: 5px; } .checkbox-group { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 5px; } .checkbox-item { display: flex; align-items: center; gap: 5px; } .section-block { border: 1px solid #e0e0e0; border-radius: 4px; padding: 15px; margin: 15px 0; background-color: #fafafa; } .section-title { font-weight: bold; color: #333; margin-bottom: 15px; } .btn { background-color: #1a73e8; color: white; border: none; padding: 10px 24px; border-radius: 4px; cursor: pointer; font-size: 14px; margin-right: 10px; } .btn:hover { background-color: #1557b0; } .btn:disabled { background-color: #ccc; cursor: not-allowed; } .btn-secondary { background-color: #5f6368; } .btn-secondary:hover { background-color: #3c4043; } .progress-container { display: none; margin-top: 20px; padding: 20px; border: 1px solid #e0e0e0; border-radius: 4px; background-color: #f8f9fa; } .progress-bar { width: 100%; height: 20px; background-color: #e0e0e0; border-radius: 10px; overflow: hidden; margin: 10px 0; } .progress-fill { height: 100%; background-color: #1a73e8; transition: width 0.3s; width: 0%; } .status-info { margin: 10px 0; font-size: 14px; } .hidden { display: none; } .search-box { margin-bottom: 10px; } .help-text { font-size: 12px; color: #666; margin-top: 5px; } .error-message { color: #d93025; font-size: 12px; margin-top: 5px; display: none; } .warning-message { color: #f57c00; font-size: 12px; margin-top: 5px; display: none; } .property-status { margin: 5px 0; padding: 8px; border-radius: 4px; font-size: 12px; } .property-ok { background-color: #e8f5e8; color: #137333; border: 1px solid #d4edda; } .property-missing { background-color: #fce8e6; color: #d93025; border: 1px solid #f5c6cb; } .property-warning { background-color: #fff3cd; color: #856404; border: 1px solid #ffeaa7; } .table-info { font-family: monospace; font-size: 11px; color: #666; } </style> </head> <body> <div class="container"> <h1>Формирование блоков картинок для разделов</h1> <form id="mainForm"> <!-- Выбор инфоблоков --> <div class="form-group"> <label for="iblocks">Выберите инфоблоки:</label> <input type="text" id="iblockSearch" placeholder="Поиск по инфоблокам..." class="search-box"> <select id="iblocks" name="iblocks" class="multi-select" multiple> <?php foreach ($iblocks as $iblock): ?> <option value="<?php echo $iblock['ID']; ?>" data-name="<?php echo strtolower($iblock['NAME']); ?>"> <?php echo htmlspecialchars($iblock['NAME']); ?> (ID: <?php echo $iblock['ID']; ?>) </option> <?php endforeach; ?> </select> <div class="help-text">Используйте Ctrl+Click для множественного выбора</div> <div id="iblockError" class="error-message">Выберите хотя бы один инфоблок</div> <div id="propertyStatus"></div> </div> <!-- Уровень вложенности --> <div class="form-group"> <label for="level">Уровень вложенности разделов:</label> <input type="number" id="level" name="level" value="3" min="1"> </div> <!-- Блок UP_IMAGES_BLOCK --> <div class="section-block"> <div class="section-title">Заполнение свойства раздела UF_UP_IMAGES_BLOCK</div> <div class="form-group"> <div class="checkbox-item"> <input type="checkbox" id="overwrite_up" name="overwrite_up"> <label for="overwrite_up">Перезаписывать значения свойства, если заполнены</label> </div> </div> <div class="form-group"> <label for="up_properties">Выберите свойства BLOCKCODE:</label> <select id="up_properties" name="up_properties" class="multi-select" multiple> <?php foreach ($blockCodeProperties as $code => $name): ?> <option value="<?php echo $code; ?>"><?php echo $name; ?></option> <?php endforeach; ?> </select> <div class="help-text">Используйте Ctrl+Click для множественного выбора</div> </div> </div> <!-- Блок DOWN_IMAGES_BLOCK --> <div class="section-block"> <div class="section-title">Заполнение свойства раздела UF_DOWN_IMAGES_BLOCK</div> <div class="form-group"> <div class="checkbox-item"> <input type="checkbox" id="overwrite_down" name="overwrite_down"> <label for="overwrite_down">Перезаписывать значения свойства, если заполнены</label> </div> </div> <div class="form-group"> <label for="down_properties">Выберите свойства BLOCKCODE:</label> <select id="down_properties" name="down_properties" class="multi-select" multiple> <?php foreach ($blockCodeProperties as $code => $name): ?> <option value="<?php echo $code; ?>"><?php echo $name; ?></option> <?php endforeach; ?> </select> <div class="help-text">Используйте Ctrl+Click для множественного выбора</div> <div id="propertiesError" class="error-message">Выберите хотя бы одно свойство для обработки</div> </div> </div> <!-- Общие параметры --> <div class="form-group"> <label for="step">Обрабатывать X разделов за шаг:</label> <input type="number" id="step" name="step" value="10" min="1"> </div> <button type="button" class="btn" onclick="startProcessing()">Запустить обработку</button> </form> <!-- Прогресс обработки --> <div id="progressContainer" class="progress-container"> <div class="status-info"> <div><strong>Текущий инфоблок:</strong> <span id="currentIblock">-</span></div> <div><strong>Текущий раздел:</strong> <span id="currentSection">-</span></div> <div><strong>Прогресс:</strong> <span id="progressText">0 / 0</span></div> </div> <div class="progress-bar"> <div class="progress-fill" id="progressFill"></div> </div> <div> <button type="button" class="btn btn-secondary" id="pauseBtn" onclick="pauseProcessing()">Приостановить</button> <button type="button" class="btn" id="resumeBtn" onclick="resumeProcessing()" style="display: none;">Продолжить</button> <button type="button" class="btn btn-secondary" onclick="stopProcessing()">Остановить</button> </div> </div> </div> <script> // Поиск по инфоблокам document.getElementById('iblockSearch').addEventListener('input', function() { const searchTerm = this.value.toLowerCase(); const options = document.querySelectorAll('#iblocks option'); options.forEach(function(option) { const name = option.dataset.name; if (name.includes(searchTerm)) { option.style.display = 'block'; } else { option.style.display = 'none'; } }); }); // Проверка свойств при изменении выбора инфоблоков document.getElementById('iblocks').addEventListener('change', function() { const selectedIblocks = Array.from(this.selectedOptions).map(option => option.value); hideErrors(); if (selectedIblocks.length > 0) { checkProperties(selectedIblocks); } else { document.getElementById('propertyStatus').innerHTML = ''; } }); function checkProperties(iblocks) { fetch(window.location.href, { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', }, body: 'action=check_properties&' + 'iblocks[]=' + iblocks.join('&iblocks[]=') }) .then(response => response.json()) .then(data => { let statusHtml = '<div style="margin-top: 15px;"><strong>Статус свойств и таблиц БД:</strong></div>'; data.forEach(function(iblock) { let statusClass = 'property-ok'; let status = ''; if (!iblock.table_exists) { statusClass = 'property-missing'; status = '✗ Таблица отсутствует'; } else if (!iblock.has_up_property && !iblock.has_down_property) { statusClass = 'property-missing'; status = '✗ Свойства отсутствуют'; } else if (!iblock.has_up_property || !iblock.has_down_property) { statusClass = 'property-warning'; status = '⚠ Не все свойства найдены'; } else { status = '✓ Все свойства найдены'; } statusHtml += '<div class="property-status ' + statusClass + '">'; statusHtml += '<div><strong>' + iblock.name + ' (ID: ' + iblock.id + ')</strong></div>'; statusHtml += '<div>Таблица: <span class="table-info">' + iblock.table_name + '</span></div>'; statusHtml += '<div>UP_IMAGES_BLOCK: ' + (iblock.has_up_property ? '✓' : '✗') + '</div>'; statusHtml += '<div>DOWN_IMAGES_BLOCK: ' + (iblock.has_down_property ? '✓' : '✗') + '</div>'; statusHtml += '<div><strong>' + status + '</strong></div>'; statusHtml += '</div>'; }); document.getElementById('propertyStatus').innerHTML = statusHtml; }) .catch(error => { console.error('Error:', error); document.getElementById('propertyStatus').innerHTML = '<div class="property-status property-missing">Ошибка при проверке свойств</div>'; }); } function hideErrors() { document.getElementById('iblockError').style.display = 'none'; document.getElementById('propertiesError').style.display = 'none'; } let isProcessing = false; let isPaused = false; let totalSections = 0; let processedSections = 0; let currentOffset = 0; function startProcessing() { hideErrors(); // Получаем данные формы const selectedIblocks = Array.from(document.getElementById('iblocks').selectedOptions).map(option => option.value); const upProperties = Array.from(document.getElementById('up_properties').selectedOptions).map(option => option.value); const downProperties = Array.from(document.getElementById('down_properties').selectedOptions).map(option => option.value); // Валидация let hasErrors = false; if (selectedIblocks.length === 0) { document.getElementById('iblockError').style.display = 'block'; hasErrors = true; } if (upProperties.length === 0 && downProperties.length === 0) { document.getElementById('propertiesError').style.display = 'block'; hasErrors = true; } if (hasErrors) { return; } isProcessing = true; isPaused = false; processedSections = 0; currentOffset = 0; document.getElementById('progressContainer').style.display = 'block'; document.querySelector('.btn').disabled = true; // Получаем общее количество разделов getSectionsCount(selectedIblocks, document.getElementById('level').value); } function getSectionsCount(iblocks, level) { fetch(window.location.href, { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', }, body: 'action=get_sections_count&' + 'iblocks[]=' + iblocks.join('&iblocks[]=') + '&level=' + level }) .then(response => response.json()) .then(data => { totalSections = data.total; updateProgress(); processSections(); }) .catch(error => { console.error('Error:', error); alert('Ошибка при получении количества разделов'); stopProcessing(); }); } function processSections() { if (!isProcessing || isPaused) { return; } const form = document.getElementById('mainForm'); const formData = new FormData(form); formData.append('action', 'process_sections'); formData.append('offset', currentOffset); // Добавляем выбранные инфоблоки const selectedIblocks = Array.from(document.getElementById('iblocks').selectedOptions).map(option => option.value); selectedIblocks.forEach(iblock => formData.append('iblocks[]', iblock)); // Добавляем выбранные свойства const upProperties = Array.from(document.getElementById('up_properties').selectedOptions).map(option => option.value); const downProperties = Array.from(document.getElementById('down_properties').selectedOptions).map(option => option.value); upProperties.forEach(prop => formData.append('up_properties[]', prop)); downProperties.forEach(prop => formData.append('down_properties[]', prop)); fetch(window.location.href, { method: 'POST', body: formData }) .then(response => response.json()) .then(data => { processedSections += data.processed; currentOffset = data.new_offset; document.getElementById('currentIblock').textContent = data.current_iblock || '-'; document.getElementById('currentSection').textContent = data.current_section || '-'; updateProgress(); if (processedSections < totalSections && data.processed > 0) { setTimeout(processSections, 100); // Небольшая пауза между запросами } else { completeProcessing(); } }) .catch(error => { console.error('Error:', error); alert('Ошибка при обработке разделов'); stopProcessing(); }); } function updateProgress() { const percentage = totalSections > 0 ? Math.round((processedSections / totalSections) * 100) : 0; document.getElementById('progressFill').style.width = percentage + '%'; document.getElementById('progressText').textContent = processedSections + ' / ' + totalSections; } function pauseProcessing() { isPaused = true; document.getElementById('pauseBtn').style.display = 'none'; document.getElementById('resumeBtn').style.display = 'inline-block'; } function resumeProcessing() { isPaused = false; document.getElementById('pauseBtn').style.display = 'inline-block'; document.getElementById('resumeBtn').style.display = 'none'; processSections(); } function stopProcessing() { isProcessing = false; isPaused = false; document.querySelector('.btn').disabled = false; document.getElementById('progressContainer').style.display = 'none'; document.getElementById('pauseBtn').style.display = 'inline-block'; document.getElementById('resumeBtn').style.display = 'none'; } function completeProcessing() { isProcessing = false; document.querySelector('.btn').disabled = false; document.getElementById('pauseBtn').style.display = 'none'; document.getElementById('resumeBtn').style.display = 'none'; alert('Обработка завершена! Обработано разделов: ' + processedSections); } </script> </body> </html>