Custom WooCommerce theme for orgsteklo.ru including: - Product catalog with category/subcategory hierarchy - Custom checkout with delivery calculation - Price calculator - Admin settings panel - Search functionality - User account pages
670 lines
35 KiB
PHP
670 lines
35 KiB
PHP
<?php
|
||
/**
|
||
* Админ-панель для управления расчетом цен на оргстекло
|
||
*/
|
||
|
||
if ( ! defined( 'ABSPATH' ) ) {
|
||
exit;
|
||
}
|
||
|
||
// Подключаем jQuery UI Sortable для админки
|
||
add_action( 'admin_enqueue_scripts', 'orgsteklo_enqueue_admin_scripts' );
|
||
function orgsteklo_enqueue_admin_scripts( $hook ) {
|
||
if ( $hook !== 'toplevel_page_orgsteklo-price-calculator' ) {
|
||
return;
|
||
}
|
||
wp_enqueue_script( 'jquery-ui-sortable' );
|
||
}
|
||
|
||
// Добавляем страницу в админку
|
||
add_action( 'admin_menu', 'orgsteklo_add_price_calculator_page' );
|
||
function orgsteklo_add_price_calculator_page() {
|
||
add_menu_page(
|
||
'Калькулятор цен на оргстекло',
|
||
'Калькулятор цен',
|
||
'manage_options',
|
||
'orgsteklo-price-calculator',
|
||
'orgsteklo_price_calculator_page',
|
||
'dashicons-calculator',
|
||
30
|
||
);
|
||
}
|
||
|
||
// Сохранение данных
|
||
add_action( 'admin_init', 'orgsteklo_save_price_calculator_settings' );
|
||
function orgsteklo_save_price_calculator_settings() {
|
||
if ( ! isset( $_POST['orgsteklo_price_calc_nonce'] ) ) {
|
||
return;
|
||
}
|
||
|
||
if ( ! wp_verify_nonce( $_POST['orgsteklo_price_calc_nonce'], 'orgsteklo_price_calc_save' ) ) {
|
||
return;
|
||
}
|
||
|
||
if ( ! current_user_can( 'manage_options' ) ) {
|
||
return;
|
||
}
|
||
|
||
// Сохраняем базовую стоимость 1 кг
|
||
if ( isset( $_POST['base_price_per_kg'] ) ) {
|
||
update_option( 'orgsteklo_base_price_per_kg', floatval( $_POST['base_price_per_kg'] ) );
|
||
}
|
||
|
||
// Сохраняем константы формул
|
||
if ( isset( $_POST['material_density'] ) ) {
|
||
update_option( 'orgsteklo_material_density', floatval( $_POST['material_density'] ) );
|
||
}
|
||
|
||
if ( isset( $_POST['custom_size_coefficient'] ) ) {
|
||
update_option( 'orgsteklo_custom_size_coefficient', floatval( $_POST['custom_size_coefficient'] ) );
|
||
}
|
||
|
||
// Сохраняем таблицы (динамическое количество)
|
||
$tables = [];
|
||
$table_count = isset( $_POST['table_count'] ) ? intval( $_POST['table_count'] ) : 5;
|
||
|
||
for ( $table_num = 1; $table_num <= $table_count; $table_num++ ) {
|
||
if ( ! isset( $_POST["table_{$table_num}_name"] ) ) {
|
||
continue;
|
||
}
|
||
|
||
$table_data = [
|
||
'name' => sanitize_text_field( $_POST["table_{$table_num}_name"] ),
|
||
'rows' => []
|
||
];
|
||
|
||
// Получаем строки таблицы
|
||
if ( isset( $_POST["table_{$table_num}_rows"] ) && is_array( $_POST["table_{$table_num}_rows"] ) ) {
|
||
foreach ( $_POST["table_{$table_num}_rows"] as $row ) {
|
||
$table_data['rows'][] = [
|
||
'thickness' => floatval( $row['thickness'] ?? 0 ),
|
||
'width' => floatval( $row['width'] ?? 0 ),
|
||
'length' => floatval( $row['length'] ?? 0 ),
|
||
'k1' => floatval( $row['k1'] ?? 1 ),
|
||
'k2' => floatval( $row['k2'] ?? 1 ),
|
||
'k3' => floatval( $row['k3'] ?? 1 ),
|
||
'k4' => floatval( $row['k4'] ?? 1 ),
|
||
'k5' => floatval( $row['k5'] ?? 1 ),
|
||
'n' => floatval( $row['n'] ?? 0 ),
|
||
];
|
||
}
|
||
}
|
||
|
||
$tables[ $table_num ] = $table_data;
|
||
}
|
||
|
||
update_option( 'orgsteklo_price_tables', $tables );
|
||
update_option( 'orgsteklo_price_tables_count', $table_count );
|
||
|
||
// Редирект с сообщением об успехе
|
||
wp_redirect( add_query_arg( 'settings-updated', 'true', wp_get_referer() ) );
|
||
exit;
|
||
}
|
||
|
||
// Страница админки
|
||
function orgsteklo_price_calculator_page() {
|
||
// Получаем сохраненные данные
|
||
$base_price = get_option( 'orgsteklo_base_price_per_kg', 300 );
|
||
$tables = get_option( 'orgsteklo_price_tables', [] );
|
||
$table_count = get_option( 'orgsteklo_price_tables_count', 5 );
|
||
|
||
// Названия таблиц по умолчанию
|
||
$default_table_names = [
|
||
1 => 'Оргстекло прозрачное, бесцветное',
|
||
2 => 'Оргстекло прозрачное, цветное',
|
||
3 => 'Оргстекло глухое, сатинированное',
|
||
4 => 'Оргстекло флуоресцентное, день/ночь, зеркальное',
|
||
5 => 'Оргстекло с особыми свойствами',
|
||
];
|
||
|
||
// Генерируем названия для дополнительных таблиц
|
||
for ( $i = 6; $i <= $table_count; $i++ ) {
|
||
$default_table_names[$i] = "Таблица {$i}";
|
||
}
|
||
|
||
?>
|
||
<div class="wrap">
|
||
<h1>Калькулятор цен на оргстекло</h1>
|
||
|
||
<?php if ( isset( $_GET['settings-updated'] ) ) : ?>
|
||
<div class="notice notice-success is-dismissible">
|
||
<p>Настройки сохранены!</p>
|
||
</div>
|
||
<?php endif; ?>
|
||
|
||
<form method="post" action="">
|
||
<?php wp_nonce_field( 'orgsteklo_price_calc_save', 'orgsteklo_price_calc_nonce' ); ?>
|
||
|
||
<!-- Базовая стоимость и константы -->
|
||
<h2>Основные параметры</h2>
|
||
<table class="form-table">
|
||
<tr>
|
||
<th scope="row">
|
||
<label for="base_price_per_kg">Базовая стоимость 1 кг (руб.)</label>
|
||
</th>
|
||
<td>
|
||
<input
|
||
type="number"
|
||
step="0.01"
|
||
name="base_price_per_kg"
|
||
id="base_price_per_kg"
|
||
value="<?php echo esc_attr( $base_price ); ?>"
|
||
class="regular-text"
|
||
>
|
||
<p class="description">При изменении этого значения пересчитываются все цены</p>
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<th scope="row">
|
||
<label for="material_density">Плотность материала (г/см³)</label>
|
||
</th>
|
||
<td>
|
||
<input
|
||
type="number"
|
||
step="0.01"
|
||
name="material_density"
|
||
id="material_density"
|
||
value="<?php echo esc_attr( get_option( 'orgsteklo_material_density', 1.19 ) ); ?>"
|
||
class="regular-text"
|
||
>
|
||
<p class="description">По умолчанию: 1.19 г/см³</p>
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<th scope="row">
|
||
<label for="custom_size_coefficient">Коэффициент отходов при нарезке</label>
|
||
</th>
|
||
<td>
|
||
<input
|
||
type="number"
|
||
step="0.01"
|
||
name="custom_size_coefficient"
|
||
id="custom_size_coefficient"
|
||
value="<?php echo esc_attr( get_option( 'orgsteklo_custom_size_coefficient', 1.2 ) ); ?>"
|
||
class="regular-text"
|
||
>
|
||
<p class="description">Множитель для нестандартных размеров. По умолчанию: 1.2</p>
|
||
</td>
|
||
</tr>
|
||
</table>
|
||
|
||
<hr>
|
||
|
||
<!-- Таблицы коэффициентов -->
|
||
<h2>Таблицы стандартных размеров, коэффициентов и надбавок</h2>
|
||
|
||
<input type="hidden" name="table_count" id="table_count" value="<?php echo esc_attr( $table_count ); ?>">
|
||
|
||
<div id="tables-container">
|
||
<?php for ( $table_num = 1; $table_num <= $table_count; $table_num++ ) : ?>
|
||
<?php
|
||
$table_name = $tables[ $table_num ]['name'] ?? $default_table_names[ $table_num ];
|
||
$rows = $tables[ $table_num ]['rows'] ?? [];
|
||
?>
|
||
|
||
<div class="orgsteklo-table-section" style="margin-bottom: 40px; padding: 20px; background: #f9f9f9; border: 1px solid #ddd;">
|
||
<h3>Таблица <?php echo $table_num; ?></h3>
|
||
|
||
<table class="form-table">
|
||
<tr>
|
||
<th scope="row">
|
||
<label for="table_<?php echo $table_num; ?>_name">Название таблицы</label>
|
||
</th>
|
||
<td>
|
||
<input
|
||
type="text"
|
||
name="table_<?php echo $table_num; ?>_name"
|
||
id="table_<?php echo $table_num; ?>_name"
|
||
value="<?php echo esc_attr( $table_name ); ?>"
|
||
class="large-text"
|
||
>
|
||
</td>
|
||
</tr>
|
||
</table>
|
||
|
||
<h4>Строки данных</h4>
|
||
<table class="wp-list-table widefat fixed striped" style="margin-top: 10px;">
|
||
<thead>
|
||
<tr>
|
||
<th>Толщина (мм)</th>
|
||
<th>Ширина (мм)</th>
|
||
<th>Длина (мм)</th>
|
||
<th>K1</th>
|
||
<th>K2</th>
|
||
<th>K3</th>
|
||
<th>K4</th>
|
||
<th>K5</th>
|
||
<th>N (надбавка, руб)</th>
|
||
<th>Действия</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody class="table-rows" data-table="<?php echo $table_num; ?>">
|
||
<?php if ( ! empty( $rows ) ) : ?>
|
||
<?php foreach ( $rows as $index => $row ) : ?>
|
||
<tr>
|
||
<td><input type="number" step="0.1" name="table_<?php echo $table_num; ?>_rows[<?php echo $index; ?>][thickness]" value="<?php echo esc_attr( $row['thickness'] ); ?>" style="width: 80px;"></td>
|
||
<td><input type="number" step="1" name="table_<?php echo $table_num; ?>_rows[<?php echo $index; ?>][width]" value="<?php echo esc_attr( $row['width'] ); ?>" style="width: 80px;"></td>
|
||
<td><input type="number" step="1" name="table_<?php echo $table_num; ?>_rows[<?php echo $index; ?>][length]" value="<?php echo esc_attr( $row['length'] ); ?>" style="width: 80px;"></td>
|
||
<td><input type="number" step="0.001" name="table_<?php echo $table_num; ?>_rows[<?php echo $index; ?>][k1]" value="<?php echo esc_attr( $row['k1'] ); ?>" style="width: 70px;"></td>
|
||
<td><input type="number" step="0.001" name="table_<?php echo $table_num; ?>_rows[<?php echo $index; ?>][k2]" value="<?php echo esc_attr( $row['k2'] ); ?>" style="width: 70px;"></td>
|
||
<td><input type="number" step="0.001" name="table_<?php echo $table_num; ?>_rows[<?php echo $index; ?>][k3]" value="<?php echo esc_attr( $row['k3'] ); ?>" style="width: 70px;"></td>
|
||
<td><input type="number" step="0.001" name="table_<?php echo $table_num; ?>_rows[<?php echo $index; ?>][k4]" value="<?php echo esc_attr( $row['k4'] ); ?>" style="width: 70px;"></td>
|
||
<td><input type="number" step="0.001" name="table_<?php echo $table_num; ?>_rows[<?php echo $index; ?>][k5]" value="<?php echo esc_attr( $row['k5'] ); ?>" style="width: 70px;"></td>
|
||
<td><input type="number" step="1" name="table_<?php echo $table_num; ?>_rows[<?php echo $index; ?>][n]" value="<?php echo esc_attr( $row['n'] ); ?>" style="width: 80px;"></td>
|
||
<td>
|
||
<button type="button" class="button copy-row" style="margin-right: 5px;">Копировать</button>
|
||
<button type="button" class="button delete-row">Удалить</button>
|
||
</td>
|
||
</tr>
|
||
<?php endforeach; ?>
|
||
<?php endif; ?>
|
||
</tbody>
|
||
</table>
|
||
<div style="margin-top: 10px;">
|
||
<button type="button" class="button add-row" data-table="<?php echo $table_num; ?>">Добавить строку</button>
|
||
<button type="button" class="button copy-table" data-table="<?php echo $table_num; ?>" style="margin-left: 10px;">Копировать всю таблицу в буфер</button>
|
||
<button type="button" class="button paste-table" data-table="<?php echo $table_num; ?>" style="margin-left: 10px;">Вставить скопированную таблицу</button>
|
||
</div>
|
||
</div>
|
||
|
||
<?php endfor; ?>
|
||
</div>
|
||
|
||
<div style="margin: 20px 0;">
|
||
<button type="button" id="add-table-btn" class="button button-secondary" style="font-size: 14px; padding: 8px 15px;">+ Добавить таблицу</button>
|
||
<p class="description" style="margin-top: 10px;">По умолчанию: 5 таблиц. Нажмите кнопку для добавления новой таблицы.</p>
|
||
</div>
|
||
|
||
<p class="submit">
|
||
<input type="submit" name="submit" id="submit" class="button button-primary" value="Сохранить изменения">
|
||
</p>
|
||
</form>
|
||
</div>
|
||
|
||
<script>
|
||
jQuery(document).ready(function($) {
|
||
// Добавление новой таблицы
|
||
$('#add-table-btn').on('click', function() {
|
||
var currentCount = parseInt($('#table_count').val());
|
||
var newTableNum = currentCount + 1;
|
||
|
||
var newTableHtml = `
|
||
<div class="orgsteklo-table-section" style="margin-bottom: 40px; padding: 20px; background: #f9f9f9; border: 1px solid #ddd;">
|
||
<h3>Таблица ${newTableNum}</h3>
|
||
<table class="form-table">
|
||
<tr>
|
||
<th scope="row">
|
||
<label for="table_${newTableNum}_name">Название таблицы</label>
|
||
</th>
|
||
<td>
|
||
<input type="text" name="table_${newTableNum}_name" id="table_${newTableNum}_name" value="Таблица ${newTableNum}" class="large-text">
|
||
</td>
|
||
</tr>
|
||
</table>
|
||
<h4>Строки данных</h4>
|
||
<table class="wp-list-table widefat fixed striped" style="margin-top: 10px;">
|
||
<thead>
|
||
<tr>
|
||
<th>Толщина (мм)</th>
|
||
<th>Ширина (мм)</th>
|
||
<th>Длина (мм)</th>
|
||
<th>K1</th>
|
||
<th>K2</th>
|
||
<th>K3</th>
|
||
<th>K4</th>
|
||
<th>K5</th>
|
||
<th>N (надбавка, руб)</th>
|
||
<th>Действия</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody class="table-rows" data-table="${newTableNum}">
|
||
</tbody>
|
||
</table>
|
||
<div style="margin-top: 10px;">
|
||
<button type="button" class="button add-row" data-table="${newTableNum}">Добавить строку</button>
|
||
<button type="button" class="button copy-table" data-table="${newTableNum}" style="margin-left: 10px;">Копировать всю таблицу в буфер</button>
|
||
<button type="button" class="button paste-table" data-table="${newTableNum}" style="margin-left: 10px;">Вставить скопированную таблицу</button>
|
||
</div>
|
||
</div>
|
||
`;
|
||
|
||
$('#tables-container').append(newTableHtml);
|
||
$('#table_count').val(newTableNum);
|
||
|
||
// Инициализируем sortable для новой таблицы
|
||
$(`.table-rows[data-table="${newTableNum}"]`).sortable({
|
||
handle: 'td:first-child',
|
||
cursor: 'move',
|
||
axis: 'y',
|
||
helper: function(e, tr) {
|
||
var $originals = tr.children();
|
||
var $helper = tr.clone();
|
||
$helper.children().each(function(index) {
|
||
$(this).width($originals.eq(index).width());
|
||
});
|
||
return $helper;
|
||
},
|
||
update: function(event, ui) {
|
||
$(this).find('tr').each(function(index) {
|
||
$(this).find('input').each(function() {
|
||
var name = $(this).attr('name');
|
||
if (name) {
|
||
var newName = name.replace(/\[\d+\]/, '[' + index + ']');
|
||
$(this).attr('name', newName);
|
||
}
|
||
});
|
||
});
|
||
}
|
||
});
|
||
|
||
alert('Таблица ' + newTableNum + ' добавлена! Не забудьте сохранить изменения.');
|
||
});
|
||
|
||
// Инициализация drag & drop для сортировки строк
|
||
$('.table-rows').sortable({
|
||
handle: 'td:first-child',
|
||
cursor: 'move',
|
||
axis: 'y',
|
||
helper: function(e, tr) {
|
||
var $originals = tr.children();
|
||
var $helper = tr.clone();
|
||
$helper.children().each(function(index) {
|
||
$(this).width($originals.eq(index).width());
|
||
});
|
||
return $helper;
|
||
},
|
||
update: function(event, ui) {
|
||
// Обновляем индексы строк после перестановки
|
||
$(this).find('tr').each(function(index) {
|
||
$(this).find('input').each(function() {
|
||
var name = $(this).attr('name');
|
||
if (name) {
|
||
var newName = name.replace(/\[\d+\]/, '[' + index + ']');
|
||
$(this).attr('name', newName);
|
||
}
|
||
});
|
||
});
|
||
}
|
||
});
|
||
|
||
// Добавление строки
|
||
$('.add-row').on('click', function() {
|
||
var tableNum = $(this).data('table');
|
||
var tbody = $('.table-rows[data-table="' + tableNum + '"]');
|
||
var rowCount = tbody.find('tr').length;
|
||
|
||
var newRow = `
|
||
<tr>
|
||
<td><input type="number" step="0.1" name="table_${tableNum}_rows[${rowCount}][thickness]" value="2" style="width: 80px;"></td>
|
||
<td><input type="number" step="1" name="table_${tableNum}_rows[${rowCount}][width]" value="2050" style="width: 80px;"></td>
|
||
<td><input type="number" step="1" name="table_${tableNum}_rows[${rowCount}][length]" value="3050" style="width: 80px;"></td>
|
||
<td><input type="number" step="0.001" name="table_${tableNum}_rows[${rowCount}][k1]" value="1" style="width: 70px;"></td>
|
||
<td><input type="number" step="0.001" name="table_${tableNum}_rows[${rowCount}][k2]" value="1" style="width: 70px;"></td>
|
||
<td><input type="number" step="0.001" name="table_${tableNum}_rows[${rowCount}][k3]" value="1" style="width: 70px;"></td>
|
||
<td><input type="number" step="0.001" name="table_${tableNum}_rows[${rowCount}][k4]" value="1" style="width: 70px;"></td>
|
||
<td><input type="number" step="0.001" name="table_${tableNum}_rows[${rowCount}][k5]" value="1" style="width: 70px;"></td>
|
||
<td><input type="number" step="1" name="table_${tableNum}_rows[${rowCount}][n]" value="0" style="width: 80px;"></td>
|
||
<td>
|
||
<button type="button" class="button copy-row" style="margin-right: 5px;">Копировать</button>
|
||
<button type="button" class="button delete-row">Удалить</button>
|
||
</td>
|
||
</tr>
|
||
`;
|
||
|
||
tbody.append(newRow);
|
||
});
|
||
|
||
// Копирование строки
|
||
$(document).on('click', '.copy-row', function() {
|
||
var $row = $(this).closest('tr');
|
||
var $tbody = $row.closest('tbody');
|
||
var tableNum = $tbody.data('table');
|
||
var rowCount = $tbody.find('tr').length;
|
||
|
||
// Получаем значения из текущей строки
|
||
var thickness = $row.find('input[name*="[thickness]"]').val();
|
||
var width = $row.find('input[name*="[width]"]').val();
|
||
var length = $row.find('input[name*="[length]"]').val();
|
||
var k1 = $row.find('input[name*="[k1]"]').val();
|
||
var k2 = $row.find('input[name*="[k2]"]').val();
|
||
var k3 = $row.find('input[name*="[k3]"]').val();
|
||
var k4 = $row.find('input[name*="[k4]"]').val();
|
||
var k5 = $row.find('input[name*="[k5]"]').val();
|
||
var n = $row.find('input[name*="[n]"]').val();
|
||
|
||
var newRow = `
|
||
<tr>
|
||
<td><input type="number" step="0.1" name="table_${tableNum}_rows[${rowCount}][thickness]" value="${thickness}" style="width: 80px;"></td>
|
||
<td><input type="number" step="1" name="table_${tableNum}_rows[${rowCount}][width]" value="${width}" style="width: 80px;"></td>
|
||
<td><input type="number" step="1" name="table_${tableNum}_rows[${rowCount}][length]" value="${length}" style="width: 80px;"></td>
|
||
<td><input type="number" step="0.001" name="table_${tableNum}_rows[${rowCount}][k1]" value="${k1}" style="width: 70px;"></td>
|
||
<td><input type="number" step="0.001" name="table_${tableNum}_rows[${rowCount}][k2]" value="${k2}" style="width: 70px;"></td>
|
||
<td><input type="number" step="0.001" name="table_${tableNum}_rows[${rowCount}][k3]" value="${k3}" style="width: 70px;"></td>
|
||
<td><input type="number" step="0.001" name="table_${tableNum}_rows[${rowCount}][k4]" value="${k4}" style="width: 70px;"></td>
|
||
<td><input type="number" step="0.001" name="table_${tableNum}_rows[${rowCount}][k5]" value="${k5}" style="width: 70px;"></td>
|
||
<td><input type="number" step="1" name="table_${tableNum}_rows[${rowCount}][n]" value="${n}" style="width: 80px;"></td>
|
||
<td>
|
||
<button type="button" class="button copy-row" style="margin-right: 5px;">Копировать</button>
|
||
<button type="button" class="button delete-row">Удалить</button>
|
||
</td>
|
||
</tr>
|
||
`;
|
||
|
||
$row.after(newRow);
|
||
alert('Строка скопирована! Новая строка добавлена после текущей.');
|
||
});
|
||
|
||
// Копирование всей таблицы в буфер обмена
|
||
$(document).on('click', '.copy-table', function() {
|
||
var tableNum = $(this).data('table');
|
||
var $tbody = $('.table-rows[data-table="' + tableNum + '"]');
|
||
var rows = [];
|
||
|
||
$tbody.find('tr').each(function() {
|
||
var $row = $(this);
|
||
rows.push({
|
||
thickness: $row.find('input[name*="[thickness]"]').val(),
|
||
width: $row.find('input[name*="[width]"]').val(),
|
||
length: $row.find('input[name*="[length]"]').val(),
|
||
k1: $row.find('input[name*="[k1]"]').val(),
|
||
k2: $row.find('input[name*="[k2]"]').val(),
|
||
k3: $row.find('input[name*="[k3]"]').val(),
|
||
k4: $row.find('input[name*="[k4]"]').val(),
|
||
k5: $row.find('input[name*="[k5]"]').val(),
|
||
n: $row.find('input[name*="[n]"]').val()
|
||
});
|
||
});
|
||
|
||
// Сохраняем в localStorage
|
||
localStorage.setItem('orgsteklo_copied_table', JSON.stringify(rows));
|
||
|
||
alert('Таблица скопирована в буфер! Используйте кнопку "Вставить скопированную таблицу" в другой таблице чтобы вставить данные.');
|
||
});
|
||
|
||
// Вставка скопированной таблицы
|
||
$(document).on('click', '.paste-table', function() {
|
||
var tableNum = $(this).data('table');
|
||
var $tbody = $('.table-rows[data-table="' + tableNum + '"]');
|
||
|
||
var copiedData = localStorage.getItem('orgsteklo_copied_table');
|
||
if (!copiedData) {
|
||
alert('Буфер пуст! Сначала скопируйте таблицу используя кнопку "Копировать всю таблицу в буфер".');
|
||
return;
|
||
}
|
||
|
||
if (!confirm('Это заменит все строки в текущей таблице. Продолжить?')) {
|
||
return;
|
||
}
|
||
|
||
var rows = JSON.parse(copiedData);
|
||
$tbody.empty();
|
||
|
||
rows.forEach(function(row, index) {
|
||
var newRow = `
|
||
<tr>
|
||
<td><input type="number" step="0.1" name="table_${tableNum}_rows[${index}][thickness]" value="${row.thickness}" style="width: 80px;"></td>
|
||
<td><input type="number" step="1" name="table_${tableNum}_rows[${index}][width]" value="${row.width}" style="width: 80px;"></td>
|
||
<td><input type="number" step="1" name="table_${tableNum}_rows[${index}][length]" value="${row.length}" style="width: 80px;"></td>
|
||
<td><input type="number" step="0.001" name="table_${tableNum}_rows[${index}][k1]" value="${row.k1}" style="width: 70px;"></td>
|
||
<td><input type="number" step="0.001" name="table_${tableNum}_rows[${index}][k2]" value="${row.k2}" style="width: 70px;"></td>
|
||
<td><input type="number" step="0.001" name="table_${tableNum}_rows[${index}][k3]" value="${row.k3}" style="width: 70px;"></td>
|
||
<td><input type="number" step="0.001" name="table_${tableNum}_rows[${index}][k4]" value="${row.k4}" style="width: 70px;"></td>
|
||
<td><input type="number" step="0.001" name="table_${tableNum}_rows[${index}][k5]" value="${row.k5}" style="width: 70px;"></td>
|
||
<td><input type="number" step="1" name="table_${tableNum}_rows[${index}][n]" value="${row.n}" style="width: 80px;"></td>
|
||
<td>
|
||
<button type="button" class="button copy-row" style="margin-right: 5px;">Копировать</button>
|
||
<button type="button" class="button delete-row">Удалить</button>
|
||
</td>
|
||
</tr>
|
||
`;
|
||
$tbody.append(newRow);
|
||
});
|
||
|
||
alert('Таблица вставлена! Не забудьте сохранить изменения.');
|
||
});
|
||
|
||
// Удаление строки
|
||
$(document).on('click', '.delete-row', function() {
|
||
if (confirm('Вы уверены что хотите удалить эту строку?')) {
|
||
$(this).closest('tr').remove();
|
||
}
|
||
});
|
||
});
|
||
</script>
|
||
|
||
<style>
|
||
.orgsteklo-table-section table input[type="number"] {
|
||
padding: 3px 5px;
|
||
}
|
||
|
||
/* Стили для drag & drop */
|
||
.table-rows tr {
|
||
cursor: move;
|
||
}
|
||
|
||
.table-rows tr:hover {
|
||
background-color: #f0f0f0;
|
||
}
|
||
|
||
.table-rows tr.ui-sortable-helper {
|
||
background-color: #fff;
|
||
box-shadow: 0 2px 8px rgba(0,0,0,0.2);
|
||
}
|
||
|
||
.table-rows tr.ui-sortable-placeholder {
|
||
background-color: #e3f2fd;
|
||
visibility: visible !important;
|
||
height: 50px;
|
||
}
|
||
|
||
.table-rows tr td:first-child {
|
||
position: relative;
|
||
}
|
||
|
||
.table-rows tr td:first-child::before {
|
||
content: '⋮⋮';
|
||
position: absolute;
|
||
left: -15px;
|
||
top: 50%;
|
||
transform: translateY(-50%);
|
||
color: #999;
|
||
font-size: 14px;
|
||
line-height: 1;
|
||
}
|
||
</style>
|
||
<?php
|
||
}
|
||
|
||
/**
|
||
* Добавляем поле "Номер таблицы" в карточку товара
|
||
*/
|
||
|
||
// Отображение поля в админке товара
|
||
add_action( 'woocommerce_product_options_general_product_data', 'orgsteklo_add_price_table_field' );
|
||
function orgsteklo_add_price_table_field() {
|
||
global $post;
|
||
|
||
// Получаем названия таблиц
|
||
$tables = get_option( 'orgsteklo_price_tables', [] );
|
||
$table_count = get_option( 'orgsteklo_price_tables_count', 5 );
|
||
$options = [
|
||
'' => '-- Не выбрано --'
|
||
];
|
||
|
||
$default_names = [
|
||
1 => 'Оргстекло прозрачное, бесцветное',
|
||
2 => 'Оргстекло прозрачное, цветное',
|
||
3 => 'Оргстекло глухое, сатинированное',
|
||
4 => 'Оргстекло флуоресцентное, день/ночь, зеркальное',
|
||
5 => 'Оргстекло с особыми свойствами',
|
||
];
|
||
|
||
for ( $i = 1; $i <= $table_count; $i++ ) {
|
||
$name = $tables[ $i ]['name'] ?? ( $default_names[$i] ?? "Таблица {$i}" );
|
||
$options[ $i ] = "Таблица {$i}: {$name}";
|
||
}
|
||
|
||
echo '<div class="options_group">';
|
||
|
||
woocommerce_wp_select(
|
||
[
|
||
'id' => '_orgsteklo_price_table',
|
||
'label' => 'Таблица расчета цен',
|
||
'description' => 'Выберите таблицу для расчета цен на оргстекло. Данные берутся из "Калькулятор цен" в меню.',
|
||
'desc_tip' => true,
|
||
'options' => $options,
|
||
]
|
||
);
|
||
|
||
woocommerce_wp_textarea_input(
|
||
[
|
||
'id' => '_orgsteklo_important_text',
|
||
'label' => 'Текст "Важно"',
|
||
'description' => 'Информационный текст под калькулятором. Оставьте пустым для стандартного текста.',
|
||
'desc_tip' => true,
|
||
'placeholder' => 'Важно: оргстекло толщиной более 6 мм...',
|
||
]
|
||
);
|
||
|
||
echo '</div>';
|
||
}
|
||
|
||
// Сохранение поля
|
||
add_action( 'woocommerce_process_product_meta', 'orgsteklo_save_price_table_field' );
|
||
function orgsteklo_save_price_table_field( $post_id ) {
|
||
$table_number = isset( $_POST['_orgsteklo_price_table'] ) ? sanitize_text_field( $_POST['_orgsteklo_price_table'] ) : '';
|
||
update_post_meta( $post_id, '_orgsteklo_price_table', $table_number );
|
||
|
||
$important_text = isset( $_POST['_orgsteklo_important_text'] ) ? wp_kses_post( $_POST['_orgsteklo_important_text'] ) : '';
|
||
update_post_meta( $post_id, '_orgsteklo_important_text', $important_text );
|
||
|
||
// Автоматически создаем вариации из таблицы калькулятора
|
||
if ( ! empty( $table_number ) && function_exists( 'orgsteklo_create_variations_from_table' ) ) {
|
||
$result = orgsteklo_create_variations_from_table( $post_id );
|
||
|
||
// Выводим alert с результатом
|
||
add_action( 'admin_notices', function() use ( $result ) {
|
||
$class = $result['success'] ? 'notice-success' : 'notice-error';
|
||
$message = $result['message'];
|
||
echo "<div class='notice $class is-dismissible'><p><strong>Вариации калькулятора:</strong> $message</p></div>";
|
||
|
||
// Дополнительно выводим JS alert для гарантии
|
||
echo "<script>alert('Вариации калькулятора: $message');</script>";
|
||
} );
|
||
}
|
||
}
|
||
|
||
// Отображение поля в вариациях (если нужно для вариативных товаров)
|
||
add_action( 'woocommerce_product_after_variable_attributes', 'orgsteklo_add_variation_price_table_field', 10, 3 );
|
||
function orgsteklo_add_variation_price_table_field( $loop, $variation_data, $variation ) {
|
||
// Получаем значение для родительского товара (вариации наследуют таблицу от родителя)
|
||
$parent_id = wp_get_post_parent_id( $variation->ID );
|
||
$parent_table = get_post_meta( $parent_id, '_orgsteklo_price_table', true );
|
||
|
||
if ( $parent_table ) {
|
||
echo '<div style="padding: 10px; background: #f0f0f0; margin: 10px 0;">';
|
||
echo '<strong>Таблица расчета цен:</strong> Таблица ' . esc_html( $parent_table ) . ' (наследуется от родительского товара)';
|
||
echo '</div>';
|
||
}
|
||
}
|