| Server IP : 104.171.130.249 / Your IP : 216.73.216.146 Web Server : nginx/1.25.5 System : Linux 0dac65491b7e 6.8.0-134-generic #134-Ubuntu SMP PREEMPT_DYNAMIC Fri Jun 26 18:43:11 UTC 2026 x86_64 User : root ( 0) PHP Version : 8.4.23 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : OFF | Perl : ON | Python : OFF | Sudo : OFF | Pkexec : OFF Directory : /var/www/html/wp-content/themes/matreshka/inc/ |
Upload File : |
<?php
/**
* Matreshka — Admin Order Metaboxes
*
* Displays all custom order fields (shipping, delivery details,
* substitution / packing preferences, payment) in the WooCommerce
* admin order edit screen as clean, styled metaboxes.
*
* @package Matreshka
*/
defined( 'ABSPATH' ) || exit;
/* ================================================================
* 1. Default order status → "processing"
* ================================================================ */
add_filter( 'woocommerce_default_order_status', function () {
return 'processing';
} );
/* ================================================================
* 2. Register single meta box (normal position, 3 columns inside)
* ================================================================ */
add_action( 'add_meta_boxes', 'matreshka_register_order_metaboxes' );
function matreshka_register_order_metaboxes() {
$screen = matreshka_get_order_screen();
add_meta_box(
'matreshka_order_details',
'🛒 Детали заказа Матрёшка',
'matreshka_metabox_order_details',
$screen,
'normal',
'high'
);
}
/**
* Helper: get correct screen ID for HPOS or legacy orders.
*/
function matreshka_get_order_screen() {
if ( class_exists( '\Automattic\WooCommerce\Internal\DataStores\Orders\CustomOrdersTableController' ) ) {
$controller = wc_get_container()->get( \Automattic\WooCommerce\Internal\DataStores\Orders\CustomOrdersTableController::class );
if ( $controller && is_callable( [ $controller, 'custom_orders_table_usage_is_enabled' ] ) && $controller->custom_orders_table_usage_is_enabled() ) {
return wc_get_page_screen_id( 'shop-order' );
}
}
return 'shop_order';
}
/**
* Helper: retrieve WC_Order from metabox callback param.
*/
function matreshka_get_order_from_metabox( $post_or_order ) {
if ( $post_or_order instanceof WC_Order ) {
return $post_or_order;
}
if ( $post_or_order instanceof WP_Post ) {
return wc_get_order( $post_or_order->ID );
}
// HPOS passes the order directly
if ( is_object( $post_or_order ) && method_exists( $post_or_order, 'get_id' ) ) {
return wc_get_order( $post_or_order->get_id() );
}
return null;
}
/* ================================================================
* 3. SINGLE METABOX — 3 columns: Доставка | Замены | Оплата
* ================================================================ */
function matreshka_metabox_order_details( $post_or_order ) {
$order = matreshka_get_order_from_metabox( $post_or_order );
if ( ! $order ) return;
matreshka_admin_metabox_styles();
echo '<div class="matreshka-mb-grid">';
// ── Column 1: Доставка и адрес ──
echo '<div class="matreshka-mb-col">';
echo '<h4 class="matreshka-mb-col-title">📦 Доставка и адрес</h4>';
matreshka_render_col_delivery( $order );
echo '</div>';
// ── Column 2: Замены и пожелания ──
echo '<div class="matreshka-mb-col">';
echo '<h4 class="matreshka-mb-col-title">🔄 Замены и пожелания</h4>';
matreshka_render_col_substitution( $order );
echo '</div>';
// ── Column 3: Оплата ──
echo '<div class="matreshka-mb-col">';
echo '<h4 class="matreshka-mb-col-title">💳 Оплата</h4>';
matreshka_render_col_payment( $order );
echo '</div>';
echo '</div>';
}
/* ── Column 1: Доставка и адрес ────────────────────────────── */
function matreshka_render_col_delivery( $order ) {
$shipping_type = $order->get_meta( '_matreshka_shipping_type' ) ?: 'delivery';
// Способ получения
echo '<div class="matreshka-mb-section">';
echo '<div class="matreshka-mb-label">Способ получения</div>';
if ( $shipping_type === 'pickup' ) {
echo '<div class="matreshka-mb-badge matreshka-mb-badge--pickup">🏪 Самовывоз</div>';
$store_name = $order->get_meta( '_matreshka_pickup_store_name' );
$store_address = $order->get_meta( '_matreshka_pickup_store_address' );
$store_phone = $order->get_meta( '_matreshka_pickup_store_phone' );
$store_hours = $order->get_meta( '_matreshka_pickup_store_hours' );
if ( $store_name || $store_address ) {
echo '<div class="matreshka-mb-card">';
if ( $store_name ) echo '<div class="matreshka-mb-row"><strong>' . esc_html( $store_name ) . '</strong></div>';
if ( $store_address ) echo '<div class="matreshka-mb-row">📍 ' . esc_html( $store_address ) . '</div>';
if ( $store_phone ) echo '<div class="matreshka-mb-row">📞 ' . esc_html( $store_phone ) . '</div>';
if ( $store_hours ) echo '<div class="matreshka-mb-row">🕐 ' . esc_html( $store_hours ) . '</div>';
echo '</div>';
}
} else {
echo '<div class="matreshka-mb-badge matreshka-mb-badge--delivery">🚚 Курьерская доставка</div>';
}
echo '</div>';
// Адрес и «Оставить у двери» — только для доставки
if ( $shipping_type !== 'pickup' ) {
// Адрес
$address = $order->get_billing_address_1() ?: $order->get_shipping_address_1();
$entrance = $order->get_meta( '_matreshka_entrance' );
$intercom = $order->get_meta( '_matreshka_intercom' );
$floor = $order->get_meta( '_matreshka_floor' );
$apartment = $order->get_meta( '_matreshka_apartment' );
$has_details = $address || $entrance || $intercom || $floor || $apartment;
if ( $has_details ) {
echo '<div class="matreshka-mb-section">';
echo '<div class="matreshka-mb-label">Адрес для доставки:</div>';
echo '<div class="matreshka-mb-card">';
if ( $address ) echo '<div class="matreshka-mb-row"><strong>📍 ' . esc_html( $address ) . '</strong></div>';
$details = [];
if ( $entrance ) $details[] = 'Подъезд: ' . esc_html( $entrance );
if ( $floor ) $details[] = 'Этаж: ' . esc_html( $floor );
if ( $apartment ) $details[] = 'Кв.: ' . esc_html( $apartment );
if ( $intercom ) $details[] = 'Домофон: ' . esc_html( $intercom );
if ( ! empty( $details ) ) {
echo '<div class="matreshka-mb-row matreshka-mb-details">' . implode( ' · ', $details ) . '</div>';
}
echo '</div>';
echo '</div>';
}
// Оставить у двери
$leave_at_door = $order->get_meta( '_matreshka_leave_at_door' );
echo '<div class="matreshka-mb-section">';
echo '<div class="matreshka-mb-label">Оставить у двери</div>';
if ( $leave_at_door === 'yes' ) {
echo '<div class="matreshka-mb-highlight">🚪 Да — оставить у двери</div>';
} else {
echo '<div class="matreshka-mb-value">Нет</div>';
}
echo '</div>';
}
// A pickup order has a general order comment rather than a courier instruction.
$courier_comment = $order->get_meta( '_matreshka_courier_comment' );
if ( ! $courier_comment ) {
$courier_comment = $order->get_customer_note();
}
if ( $courier_comment ) {
$comment_label = $shipping_type === 'pickup' ? 'Комментарий к заказу' : 'Комментарий курьеру';
echo '<div class="matreshka-mb-section">';
echo '<div class="matreshka-mb-label">' . esc_html( $comment_label ) . '</div>';
echo '<div class="matreshka-mb-note">💬 ' . esc_html( $courier_comment ) . '</div>';
echo '</div>';
}
// Телефон
$phone = $order->get_billing_phone();
if ( $phone ) {
echo '<div class="matreshka-mb-section">';
echo '<div class="matreshka-mb-label">Телефон</div>';
echo '<div class="matreshka-mb-value">📞 <a href="tel:' . esc_attr( $phone ) . '">' . esc_html( $phone ) . '</a></div>';
echo '</div>';
}
}
/* ── Column 2: Замены и пожелания ──────────────────────────── */
function matreshka_render_col_substitution( $order ) {
$type = $order->get_meta( '_matreshka_substitution_label' );
$comment = $order->get_meta( '_matreshka_packer_comment' );
$bags = $order->get_meta( '_matreshka_less_bags' );
$vegs = $order->get_meta( '_matreshka_vegs_in_bags' );
if ( ! $type && ! $comment && $bags !== 'yes' && $vegs !== 'yes' ) {
echo '<p class="matreshka-mb-empty">Нет особых пожеланий</p>';
return;
}
// Если не в наличии
if ( $type ) {
echo '<div class="matreshka-mb-section">';
echo '<div class="matreshka-mb-label">Если не в наличии</div>';
$type_key = $order->get_meta( '_matreshka_substitution_type' );
$icon = '📞';
if ( $type_key === 'no_replace' ) $icon = '🚫';
elseif ( $type_key === 'auto_replace' ) $icon = '🔄';
echo '<div class="matreshka-mb-badge matreshka-mb-badge--substitution">' . $icon . ' ' . esc_html( $type ) . '</div>';
echo '</div>';
}
// Пакеты
if ( $bags === 'yes' || $vegs === 'yes' ) {
echo '<div class="matreshka-mb-section">';
echo '<div class="matreshka-mb-label">Упаковка</div>';
if ( $bags === 'yes' ) echo '<div class="matreshka-mb-check">✅ Меньше пакетов</div>';
if ( $vegs === 'yes' ) echo '<div class="matreshka-mb-check">✅ Овощи в пакетах</div>';
echo '</div>';
}
// Комментарий сборщику
if ( $comment ) {
echo '<div class="matreshka-mb-section">';
echo '<div class="matreshka-mb-label">Комментарий сборщику</div>';
echo '<div class="matreshka-mb-note">💬 ' . esc_html( $comment ) . '</div>';
echo '</div>';
}
}
/* ── Column 3: Оплата ─────────────────────────────────────── */
function matreshka_render_col_payment( $order ) {
$method = $order->get_payment_method();
$method_title = $order->get_payment_method_title();
$is_paid = $order->is_paid();
// Способ оплаты
echo '<div class="matreshka-mb-section">';
echo '<div class="matreshka-mb-label">Способ оплаты</div>';
if ( $method_title ) {
$icon = '💵';
if ( $method === 'bacs' || strpos( $method, 'card' ) !== false || strpos( $method, 'stripe' ) !== false ) {
$icon = '💳';
}
echo '<div class="matreshka-mb-value">' . $icon . ' ' . esc_html( $method_title ) . '</div>';
} else {
echo '<div class="matreshka-mb-empty">Не указан</div>';
}
echo '</div>';
// Статус оплаты
echo '<div class="matreshka-mb-section">';
echo '<div class="matreshka-mb-label">Статус оплаты</div>';
if ( $is_paid ) {
$date_paid = $order->get_date_paid();
echo '<div class="matreshka-mb-badge matreshka-mb-badge--paid">✅ Оплачен';
if ( $date_paid ) {
echo ' <span class="matreshka-mb-date">' . esc_html( $date_paid->date_i18n( 'd.m.Y H:i' ) ) . '</span>';
}
echo '</div>';
} else {
echo '<div class="matreshka-mb-badge matreshka-mb-badge--unpaid">⏳ Ожидает оплаты</div>';
}
echo '</div>';
// Сумма
echo '<div class="matreshka-mb-section">';
echo '<div class="matreshka-mb-label">Сумма заказа</div>';
echo '<div class="matreshka-mb-value matreshka-mb-total">' . wp_kses_post( $order->get_formatted_order_total() ) . '</div>';
echo '</div>';
}
/* ================================================================
* 4. Inline styles (rendered once)
* ================================================================ */
function matreshka_admin_metabox_styles() {
static $printed = false;
if ( $printed ) return;
$printed = true;
?>
<style>
/* ── Matreshka Admin Order — 3-column grid ── */
.matreshka-mb-grid {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
gap: 0;
}
.matreshka-mb-col {
padding: 16px 20px;
border-right: 1px solid #e0e0e0;
}
.matreshka-mb-col:last-child {
border-right: none;
}
.matreshka-mb-col-title {
font-size: 14px;
font-weight: 600;
margin: 0 0 14px 0;
padding-bottom: 10px;
border-bottom: 2px solid #e0e0e0;
color: #1d2327;
}
/* ── Sections ── */
.matreshka-mb-section {
margin-bottom: 14px;
padding-bottom: 12px;
border-bottom: 1px solid #f0f0f0;
}
.matreshka-mb-section:last-child {
margin-bottom: 0;
padding-bottom: 0;
border-bottom: none;
}
.matreshka-mb-label {
font-size: 11px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.5px;
color: #888;
margin-bottom: 6px;
}
.matreshka-mb-value {
font-size: 13px;
color: #1d2327;
line-height: 1.5;
}
.matreshka-mb-value a {
color: #2271b1;
text-decoration: none;
}
.matreshka-mb-value a:hover {
text-decoration: underline;
}
.matreshka-mb-total {
font-size: 18px;
font-weight: 700;
}
/* ── Badges ── */
.matreshka-mb-badge {
display: inline-block;
padding: 4px 10px;
border-radius: 4px;
font-size: 12px;
font-weight: 600;
line-height: 1.6;
}
.matreshka-mb-badge--delivery {
background: #e8f5e9;
color: #2e7d32;
}
.matreshka-mb-badge--pickup {
background: #e3f2fd;
color: #1565c0;
}
.matreshka-mb-badge--substitution {
background: #fff3e0;
color: #e65100;
}
.matreshka-mb-badge--paid {
background: #e8f5e9;
color: #2e7d32;
}
.matreshka-mb-badge--unpaid {
background: #fff8e1;
color: #f57f17;
}
.matreshka-mb-date {
font-weight: 400;
opacity: .7;
margin-left: 4px;
}
/* ── Cards & details ── */
.matreshka-mb-card {
background: #f6f7f7;
border: 1px solid #e0e0e0;
border-radius: 6px;
padding: 10px 12px;
margin-top: 6px;
}
.matreshka-mb-row {
font-size: 12px;
color: #1d2327;
line-height: 1.7;
}
.matreshka-mb-details {
color: #666;
font-size: 11.5px;
}
.matreshka-mb-note {
background: #fffde7;
border-left: 3px solid #ffc107;
padding: 8px 10px;
border-radius: 0 4px 4px 0;
font-size: 12px;
color: #5d4037;
margin-top: 8px;
line-height: 1.5;
}
.matreshka-mb-highlight {
margin-top: 0;
padding: 6px 10px;
background: #fce4ec;
border-radius: 4px;
font-size: 12px;
font-weight: 600;
color: #c62828;
}
.matreshka-mb-check {
font-size: 12px;
line-height: 1.8;
color: #1d2327;
}
.matreshka-mb-empty {
color: #999;
font-style: italic;
font-size: 12px;
}
/* ── Responsive: stack on narrow screens ── */
@media screen and (max-width: 1200px) {
.matreshka-mb-grid {
grid-template-columns: 1fr;
}
.matreshka-mb-col {
border-right: none;
border-bottom: 1px solid #e0e0e0;
padding: 14px 16px;
}
.matreshka-mb-col:last-child {
border-bottom: none;
}
}
</style>
<?php
}