403Webshell
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 :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /var/www/html/wp-content/themes/matreshka/inc/cashback.php
<?php
/**
 * Cashback System for Matreshka
 *
 * Features:
 * - Admin settings page (global %, per-category %, whitelist, user limit)
 * - Cashback accrual on completed orders
 * - Cashback redemption at checkout (as WC fee)
 * - User category selection (from admin whitelist)
 * - Cart/checkout cashback display
 * - Admin reset all users' category selections
 *
 * @package Matreshka
 */

if ( ! defined( 'ABSPATH' ) ) exit;

// ================================================================
// 1. ADMIN SETTINGS PAGE
// ================================================================

add_action( 'admin_menu', function() {
	add_menu_page(
		'Настройки кешбека',
		'Кешбек',
		'manage_options',
		'matreshka-cashback',
		'matreshka_cashback_admin_page',
		'dashicons-money-alt',
		58
	);
} );

add_action( 'admin_init', function() {
	register_setting( 'matreshka_cashback_group', 'matreshka_cashback_default_percent', [
		'type' => 'number', 'default' => 0.5,
		'sanitize_callback' => function( $v ) { return max( 0, min( 100, floatval( $v ) ) ); },
	] );
	register_setting( 'matreshka_cashback_group', 'matreshka_cashback_category_percents', [
		'type' => 'array',
		'sanitize_callback' => 'matreshka_sanitize_category_percents',
	] );
	register_setting( 'matreshka_cashback_group', 'matreshka_cashback_whitelist', [
		'type' => 'array',
		'sanitize_callback' => function( $v ) { return is_array( $v ) ? array_map( 'absint', $v ) : []; },
	] );
	register_setting( 'matreshka_cashback_group', 'matreshka_cashback_user_limit', [
		'type' => 'integer', 'default' => 3,
		'sanitize_callback' => function( $v ) { return max( 1, absint( $v ) ); },
	] );
} );

function matreshka_sanitize_category_percents( $data ) {
	if ( ! is_array( $data ) ) return [];
	$clean = [];
	foreach ( $data as $cat_id => $pct ) {
		$cat_id = absint( $cat_id );
		$pct    = floatval( $pct );
		if ( $cat_id && $pct > 0 ) {
			$clean[ $cat_id ] = min( 100, $pct );
		}
	}
	return $clean;
}

/**
 * Get all cashback settings
 */
function matreshka_cashback_settings() {
	static $cache = null;
	if ( $cache !== null ) return $cache;

	$cache = [
		'default_percent'    => floatval( get_option( 'matreshka_cashback_default_percent', 0.5 ) ),
		'category_percents'  => get_option( 'matreshka_cashback_category_percents', [] ) ?: [],
		'whitelist'          => get_option( 'matreshka_cashback_whitelist', [] ) ?: [],
		'user_limit'         => absint( get_option( 'matreshka_cashback_user_limit', 3 ) ),
	];
	return $cache;
}

/**
 * Admin page renderer
 */
function matreshka_cashback_admin_page() {
	// Handle reset action
	if ( isset( $_POST['matreshka_reset_cashback_categories'] ) && check_admin_referer( 'matreshka_reset_cashback' ) ) {
		$users = get_users( [ 'fields' => 'ID' ] );
		foreach ( $users as $uid ) {
			delete_user_meta( $uid, 'matreshka_cashback_categories' );
		}
		echo '<div class="notice notice-success"><p>Категории кешбека сброшены для всех пользователей.</p></div>';
	}

	$settings   = matreshka_cashback_settings();
	$categories = get_terms( [ 'taxonomy' => 'product_cat', 'hide_empty' => false, 'orderby' => 'name' ] );
	if ( is_wp_error( $categories ) ) $categories = [];
	?>
	<div class="wrap">
		<h1>Настройки кешбека</h1>

		<form method="post" action="options.php">
			<?php settings_fields( 'matreshka_cashback_group' ); ?>

			<h2>Общие настройки</h2>
			<table class="form-table">
				<tr>
					<th><label for="cb_default">Общий % кешбека</label></th>
					<td>
						<input type="number" id="cb_default" name="matreshka_cashback_default_percent"
							   value="<?php echo esc_attr( $settings['default_percent'] ); ?>"
							   step="0.1" min="0" max="100" style="width:80px;"> %
						<p class="description">Применяется ко всем категориям, если не задан индивидуальный %.</p>
					</td>
				</tr>
				<tr>
					<th><label for="cb_limit">Макс. категорий для пользователя</label></th>
					<td>
						<input type="number" id="cb_limit" name="matreshka_cashback_user_limit"
							   value="<?php echo esc_attr( $settings['user_limit'] ); ?>"
							   min="1" max="20" style="width:60px;">
						<p class="description">Сколько категорий кешбека может активировать 1 пользователь.</p>
					</td>
				</tr>
			</table>

			<h2>Белый список категорий <small>(для выбора пользователями)</small></h2>
			<p class="description">Отметьте категории, из которых пользователи смогут выбрать себе категории повышенного кешбека.</p>

			<table class="widefat striped" style="max-width:700px;">
				<thead>
					<tr>
						<th style="width:30px;">&nbsp;</th>
						<th>Категория</th>
						<th style="width:120px;">Кешбек (%)</th>
					</tr>
				</thead>
				<tbody>
					<?php foreach ( $categories as $cat ) :
						$in_whitelist = in_array( $cat->term_id, $settings['whitelist'] );
						$pct = $settings['category_percents'][ $cat->term_id ] ?? '';
					?>
					<tr>
						<td>
							<input type="checkbox" name="matreshka_cashback_whitelist[]"
								   value="<?php echo esc_attr( $cat->term_id ); ?>"
								   <?php checked( $in_whitelist ); ?>>
						</td>
						<td><?php echo esc_html( $cat->name ); ?> <small class="text-muted">(<?php echo $cat->count; ?> товаров)</small></td>
						<td>
							<input type="number" name="matreshka_cashback_category_percents[<?php echo esc_attr( $cat->term_id ); ?>]"
								   value="<?php echo esc_attr( $pct ); ?>"
								   step="0.1" min="0" max="100" style="width:80px;"
								   placeholder="<?php echo esc_attr( $settings['default_percent'] ); ?>">
						</td>
					</tr>
					<?php endforeach; ?>
				</tbody>
			</table>

			<?php submit_button( 'Сохранить настройки' ); ?>
		</form>

		<hr>
		<h2>Сброс категорий</h2>
		<p>Удалить у всех пользователей выбранные категории кешбека. Пользователи смогут выбрать заново.</p>
		<form method="post">
			<?php wp_nonce_field( 'matreshka_reset_cashback' ); ?>
			<button type="submit" name="matreshka_reset_cashback_categories" value="1"
					class="button button-secondary" onclick="return confirm('Вы уверены? Категории кешбека будут сброшены у ВСЕХ пользователей.');">
				🔄 Сбросить категории всех пользователей
			</button>
		</form>
	</div>
	<?php
}

// ================================================================
// 2. CASHBACK CALCULATION HELPERS
// ================================================================

/**
 * Get cashback percent for a specific product
 * Priority: user selected category > category custom % > default %
 */
function matreshka_get_product_cashback_percent( $product_id, $user_id = null ) {
	$settings = matreshka_cashback_settings();
	$default  = $settings['default_percent'];

	// Get product categories
	$cats = wp_get_post_terms( $product_id, 'product_cat', [ 'fields' => 'ids' ] );
	if ( is_wp_error( $cats ) || empty( $cats ) ) return $default;

	// Check if user has selected cashback categories
	$user_cats = [];
	if ( $user_id ) {
		$user_cats = get_user_meta( $user_id, 'matreshka_cashback_categories', true );
		$user_cats = is_array( $user_cats ) ? $user_cats : [];
	}

	$best_percent = $default;

	foreach ( $cats as $cat_id ) {
		// Elevated rate only if user selected this category
		if ( in_array( $cat_id, $user_cats ) && isset( $settings['category_percents'][ $cat_id ] ) ) {
			$best_percent = max( $best_percent, $settings['category_percents'][ $cat_id ] );
		}
	}

	return $best_percent;
}

/**
 * Calculate total cashback for the current cart
 */
function matreshka_calculate_cart_cashback( $user_id = null ) {
	if ( ! $user_id && is_user_logged_in() ) {
		$user_id = get_current_user_id();
	}
	if ( ! $user_id || ! WC()->cart ) return 0;

	$settings  = matreshka_cashback_settings();
	$user_cats = get_user_meta( $user_id, 'matreshka_cashback_categories', true );
	$user_cats = is_array( $user_cats ) ? $user_cats : [];
	$total_cb  = 0;

	foreach ( WC()->cart->get_cart() as $item ) {
		$product_id = $item['product_id'];
		$line_total = $item['line_total']; // After discounts

		$cats = wp_get_post_terms( $product_id, 'product_cat', [ 'fields' => 'ids' ] );
		if ( is_wp_error( $cats ) ) $cats = [];

		$percent = $settings['default_percent'];

		// Check if any product category is in user's selected cashback categories
		foreach ( $cats as $cat_id ) {
			if ( in_array( $cat_id, $user_cats ) && isset( $settings['category_percents'][ $cat_id ] ) ) {
				$percent = max( $percent, $settings['category_percents'][ $cat_id ] );
			}
		}

		$total_cb += $line_total * ( $percent / 100 );
	}

	return round( $total_cb, 2 );
}

/**
 * Calculate cashback for a completed order
 */
function matreshka_calculate_order_cashback( $order ) {
	$user_id = $order->get_user_id();
	if ( ! $user_id ) return 0;

	$settings  = matreshka_cashback_settings();
	$user_cats = get_user_meta( $user_id, 'matreshka_cashback_categories', true );
	$user_cats = is_array( $user_cats ) ? $user_cats : [];
	$total_cb  = 0;

	foreach ( $order->get_items() as $item ) {
		$product_id = $item->get_product_id();
		$line_total = $item->get_total(); // After discounts

		$cats = wp_get_post_terms( $product_id, 'product_cat', [ 'fields' => 'ids' ] );
		if ( is_wp_error( $cats ) ) $cats = [];

		$percent = $settings['default_percent'];

		foreach ( $cats as $cat_id ) {
			if ( in_array( $cat_id, $user_cats ) && isset( $settings['category_percents'][ $cat_id ] ) ) {
				$percent = max( $percent, $settings['category_percents'][ $cat_id ] );
			}
		}

		$total_cb += $line_total * ( $percent / 100 );
	}

	return round( $total_cb, 2 );
}

// ================================================================
// 3. ORDER HOOKS — ACCRUAL ON COMPLETED
// ================================================================

add_action( 'woocommerce_order_status_completed', 'matreshka_cashback_award', 20 );
function matreshka_cashback_award( $order_id ) {
	$order = wc_get_order( $order_id );
	if ( ! $order ) return;

	// Don't award twice
	if ( $order->get_meta( '_matreshka_cashback_awarded' ) ) return;

	$user_id = $order->get_user_id();
	if ( ! $user_id ) return;

	$cashback = matreshka_calculate_order_cashback( $order );
	if ( $cashback <= 0 ) return;

	// Convert rubles to bonus points (1 ₽ = 10 бонусов, rate 0.1)
	$bonus_points = floor( $cashback / 0.1 );

	matreshka_add_user_bonuses( $user_id, $bonus_points );
	$order->update_meta_data( '_matreshka_cashback_awarded', $bonus_points );
	$order->update_meta_data( '_matreshka_cashback_amount', $cashback );
	$order->save();

	$order->add_order_note( sprintf( 'Кешбек начислен: %s (%d бонусов)', matreshka_bonuses_to_money( $bonus_points ), $bonus_points ) );
}

// ================================================================
// 4. CASHBACK REDEMPTION AT CHECKOUT (as negative fee)
// ================================================================

/**
 * Return the maximum number of whole bonus points that can be redeemed now.
 *
 * One point is worth 0.1 ₽.  Bonuses may pay for up to 50% of the products'
 * price after coupon discounts; delivery and other fees are not discountable.
 */
function matreshka_get_redeemable_bonus_points( $cart = null, $user_id = 0 ) {
	$cart    = $cart ?: ( WC()->cart ?? null );
	$user_id = $user_id ?: get_current_user_id();

	if ( ! $cart || ! $user_id ) {
		return 0;
	}

	$balance       = matreshka_get_user_bonuses( $user_id );
	$products_total = max( 0, (float) $cart->get_cart_contents_total() );
	$max_by_order  = (int) floor( ( $products_total * 0.5 ) / 0.1 + 0.00001 );

	return max( 0, min( $balance, $max_by_order ) );
}

/**
 * Convert whole bonus points into a WooCommerce fee amount.
 */
function matreshka_bonus_redemption_amount( $points ) {
	return round( absint( $points ) * 0.1, wc_get_price_decimals() );
}

// Store the number of bonus points to redeem in the session.
add_action( 'wp_ajax_matreshka_apply_cashback', 'matreshka_ajax_apply_cashback' );
function matreshka_ajax_apply_cashback() {
	check_ajax_referer( 'matreshka_cashback_nonce', 'nonce' );

	if ( ! is_user_logged_in() ) {
		wp_send_json_error( [ 'message' => 'Не авторизован' ] );
	}

	$requested_points = isset( $_POST['bonus_points'] ) ? absint( wp_unslash( $_POST['bonus_points'] ) ) : 0;
	$max_points       = matreshka_get_redeemable_bonus_points();

	if ( $requested_points <= 0 || $max_points <= 0 ) {
		WC()->session->set( 'matreshka_cashback_redeem_points', 0 );
		WC()->session->set( 'matreshka_cashback_redeem', 0 ); // Clear the legacy session value.
		wp_send_json_success( [ 'message' => 'Кешбек снят', 'applied' => 0 ] );
	}

	$points = min( $requested_points, $max_points );
	WC()->session->set( 'matreshka_cashback_redeem_points', $points );
	WC()->session->set( 'matreshka_cashback_redeem', 0 ); // Clear the legacy session value.
	wp_send_json_success( [
		'message'        => 'Бонусы применены',
		'applied_points' => $points,
		'applied_amount' => matreshka_bonus_redemption_amount( $points ),
	] );
}

// Remove cashback
add_action( 'wp_ajax_matreshka_remove_cashback', 'matreshka_ajax_remove_cashback' );
function matreshka_ajax_remove_cashback() {
	check_ajax_referer( 'matreshka_cashback_nonce', 'nonce' );

	if ( ! is_user_logged_in() ) {
		wp_send_json_error( [ 'message' => 'Не авторизован' ] );
	}

	WC()->session->set( 'matreshka_cashback_redeem_points', 0 );
	WC()->session->set( 'matreshka_cashback_redeem', 0 ); // Clear the legacy session value.
	wp_send_json_success( [ 'message' => 'Кешбек снят' ] );
}

// Add negative fee for cashback redemption (with server-side revalidation)
add_action( 'woocommerce_cart_calculate_fees', 'matreshka_cashback_add_fee' );
function matreshka_cashback_add_fee( $cart ) {
	if ( is_admin() && ! defined( 'DOING_AJAX' ) ) return;
	if ( ! is_user_logged_in() ) return;

	$points = WC()->session ? absint( WC()->session->get( 'matreshka_cashback_redeem_points', 0 ) ) : 0;
	if ( $points <= 0 ) return;

	// Revalidate the balance and 50% rule every time WooCommerce recalculates.
	$points = min( $points, matreshka_get_redeemable_bonus_points( $cart ) );

	if ( $points > 0 ) {
		$cart->add_fee( 'Списание бонусов', -matreshka_bonus_redemption_amount( $points ), false );
	} else {
		WC()->session->set( 'matreshka_cashback_redeem_points', 0 );
	}
}

// Deduct bonuses when order is placed (with final revalidation)
add_action( 'woocommerce_checkout_order_processed', 'matreshka_cashback_deduct_on_order', 10, 3 );
function matreshka_cashback_deduct_on_order( $order_id, $posted_data, $order ) {
	if ( $order->get_meta( '_matreshka_cashback_redeemed_points' ) ) return;

	$user_id = $order->get_user_id();
	if ( ! $user_id ) return;

	// Deduct exactly the amount that was added to this order as a discount.
	$redeem = 0.0;
	foreach ( $order->get_items( 'fee' ) as $fee ) {
		if ( 'Списание бонусов' === $fee->get_name() ) {
			$redeem += abs( (float) $fee->get_total() );
		}
	}

	$points = (int) round( $redeem / 0.1 );
	$points = min( $points, matreshka_get_user_bonuses( $user_id ) );
	if ( $points <= 0 ) {
		if ( WC()->session ) {
			WC()->session->set( 'matreshka_cashback_redeem_points', 0 );
		}
		return;
	}

	$redeem = matreshka_bonus_redemption_amount( $points );
	matreshka_subtract_user_bonuses( $user_id, $points );
	$order->update_meta_data( '_matreshka_cashback_redeemed', $redeem );
	$order->update_meta_data( '_matreshka_cashback_redeemed_points', $points );
	$order->save();
	$order->add_order_note( sprintf( 'Списано бонусами: %s (%d бонусов)', matreshka_bonuses_to_money( $points ), $points ) );

	// Clear session
	WC()->session->set( 'matreshka_cashback_redeem_points', 0 );
}

// ================================================================
// 5. CART & CHECKOUT DISPLAY HOOKS
// ================================================================

// Add cashback info line in cart totals
add_action( 'woocommerce_after_cart_totals', 'matreshka_cashback_cart_display' );
function matreshka_cashback_cart_display() {
	if ( ! is_user_logged_in() ) return;
	$cashback = matreshka_calculate_cart_cashback();
	if ( $cashback <= 0 ) return;
	$cashback_bonuses = floor( $cashback / 0.1 );
	$user_balance     = matreshka_get_user_bonuses( get_current_user_id() );
	$tpl              = get_template_directory_uri();
	?>
	<div class="matreshka-cashback-info">
		<div class="cashback-info-row">
			<div class="cashback-info-icon">
				<img src="<?php echo esc_url( $tpl . '/assets/icons/UndoLeftRound.svg' ); ?>" alt="" width="24" height="24">
			</div>
			<span class="cashback-info-label montserrat-bold">Кешбек</span>
		</div>
		<div class="cashback-info-body">
			<span class="cashback-info-title montserrat-bold">+<?php echo esc_html( $cashback_bonuses ); ?> бонусов</span>
			<span class="cashback-info-sub montserrat-medium">≈&nbsp;<?php echo matreshka_bonuses_to_money( $cashback_bonuses ); ?></span>
		</div>
		<?php if ( $user_balance > 0 ) : ?>
		<div class="cashback-info-balance montserrat-medium">
			<img src="<?php echo esc_url( $tpl . '/assets/icons/matreshka.svg' ); ?>" alt="" width="16" height="16">
			<span>Сейчас на счёте <strong><?php echo esc_html( $user_balance ); ?></strong> бонусов (<?php echo matreshka_bonuses_to_money( $user_balance ); ?>)</span>
		</div>
		<?php endif; ?>
		<span class="cashback-info-note montserrat-medium fw-bold">Начисляются после выполнения заказа</span>
	</div>
	<?php
}

// Show the applied redemption on checkout.  The amount is selected in the cart.
add_action( 'woocommerce_review_order_before_submit', 'matreshka_cashback_checkout_display' );
function matreshka_cashback_checkout_display() {
	if ( ! is_user_logged_in() ) return;

	$user_id           = get_current_user_id();
	$balance           = matreshka_get_user_bonuses( $user_id );
	$cashback          = matreshka_calculate_cart_cashback();
	$cashback_bonuses = floor( $cashback / 0.1 );
	$redeem_points      = WC()->session ? absint( WC()->session->get( 'matreshka_cashback_redeem_points', 0 ) ) : 0;
	$redeem_points      = min( $redeem_points, matreshka_get_redeemable_bonus_points() );
	?>
	<div class="matreshka-cashback-checkout" id="cashback-checkout">
		<?php if ( $cashback > 0 ) : ?>
		<div class="cashback-earn montserrat-medium mb-2">
			<img src="<?php echo esc_url( get_template_directory_uri() . '/assets/icons/UndoLeftRound.svg' ); ?>" alt="" width="18" class="me-1">
			Кешбек: <strong class="text-success">+<?php echo esc_html( $cashback_bonuses ); ?> бонусов</strong>
			<span class="text-dark-opacity">(<?php echo matreshka_bonuses_to_money( $cashback_bonuses ); ?>)</span>
		</div>
		<?php endif; ?>

		<?php if ( $balance > 0 ) : ?>
			<div class="cashback-balance montserrat-medium">
				На счёте: <strong><?php echo esc_html( $balance ); ?> бонусов</strong>
				<span class="text-dark-opacity">(<?php echo matreshka_bonuses_to_money( $balance ); ?>)</span>
			</div>
		<?php endif; ?>

		<?php if ( $redeem_points > 0 ) : ?>
			<div class="cashback-earn montserrat-medium mt-2">
				Списано бонусами: <strong><?php echo esc_html( $redeem_points ); ?></strong>
				<span class="text-dark-opacity">(<?php echo matreshka_bonuses_to_money( $redeem_points ); ?>)</span>
			</div>
		<?php endif; ?>
	</div>
	<?php
}

// Enqueue cashback CSS globally + JS data on checkout
add_action( 'wp_enqueue_scripts', function() {
	wp_enqueue_style( 'matreshka-cashback', get_template_directory_uri() . '/assets/css/cashback.css', [], '1.3.1' );

	if ( ! is_checkout() && ! is_cart() ) return;
	if ( ! is_user_logged_in() ) return;

	$cb_balance = matreshka_get_user_bonuses( get_current_user_id() );
	wp_localize_script( 'jquery', 'matreshka_cashback', [
		'ajax_url'      => admin_url( 'admin-ajax.php' ),
		'nonce'         => wp_create_nonce( 'matreshka_cashback_nonce' ),
		'balance'       => $cb_balance,
		'balance_money' => $cb_balance * 0.1,
	] );
} );

// ================================================================
// 6. USER CATEGORY SELECTION
// ================================================================

// Route: /cashback-categories/
add_action( 'init', function() {
	add_rewrite_rule( '^cashback-categories/?$', 'index.php?matreshka_cashback_page=1', 'top' );
} );

add_filter( 'query_vars', function( $vars ) {
	$vars[] = 'matreshka_cashback_page';
	return $vars;
} );

add_filter( 'template_include', function( $template ) {
	if ( get_query_var( 'matreshka_cashback_page' ) ) {
		$t = get_theme_file_path( 'page-cashback-categories.php' );
		if ( file_exists( $t ) ) return $t;
	}
	return $template;
} );

// Flush rewrite once
add_action( 'init', function() {
	if ( ! get_option( 'matreshka_cashback_rewrite_v1' ) ) {
		flush_rewrite_rules();
		update_option( 'matreshka_cashback_rewrite_v1', 1 );
	}
}, 99 );

// AJAX: Save user's selected cashback categories
add_action( 'wp_ajax_matreshka_save_cashback_categories', 'matreshka_save_cashback_categories' );
function matreshka_save_cashback_categories() {
	check_ajax_referer( 'matreshka_cashback_nonce', 'nonce' );
	if ( ! is_user_logged_in() ) wp_send_json_error( [ 'message' => 'Не авторизован' ] );

	$settings = matreshka_cashback_settings();
	$selected = isset( $_POST['categories'] ) ? array_map( 'absint', (array) $_POST['categories'] ) : [];

	// Validate: only from whitelist
	$selected = array_intersect( $selected, $settings['whitelist'] );

	// Enforce limit
	$selected = array_slice( $selected, 0, $settings['user_limit'] );

	update_user_meta( get_current_user_id(), 'matreshka_cashback_categories', $selected );
	wp_send_json_success( [ 'message' => 'Категории сохранены', 'selected' => $selected ] );
}

/**
 * Get user's selected cashback categories
 */
function matreshka_get_user_cashback_categories( $user_id = null ) {
	if ( ! $user_id ) $user_id = get_current_user_id();
	$cats = get_user_meta( $user_id, 'matreshka_cashback_categories', true );
	return is_array( $cats ) ? $cats : [];
}

/**
 * Get formatted whitelist categories with their percentages
 */
function matreshka_get_cashback_whitelist_data() {
	$settings = matreshka_cashback_settings();
	$data = [];
	foreach ( $settings['whitelist'] as $cat_id ) {
		$term = get_term( $cat_id, 'product_cat' );
		if ( ! $term || is_wp_error( $term ) ) continue;
		$data[] = [
			'id'      => $cat_id,
			'name'    => $term->name,
			'slug'    => $term->slug,
			'percent' => $settings['category_percents'][ $cat_id ] ?? $settings['default_percent'],
			'image'   => matreshka_get_category_thumb_url( $cat_id ),
		];
	}
	return $data;
}

function matreshka_get_category_thumb_url( $cat_id ) {
	$thumb_id = get_term_meta( $cat_id, 'thumbnail_id', true );
	return $thumb_id ? wp_get_attachment_image_url( $thumb_id, 'woocommerce_thumbnail' ) : '';
}

Youez - 2016 - github.com/yon3zu
LinuXploit