Воеводский Михаил

Воеводский Михаил

Был в сети 30 марта 2026, 14:44
Заказы не принимаю
$cartArray = $cart->get(); // Массик товаров в корзине
$cartProduct =	$cartArray[$key]; // Один товар в корзине
Ты получаешь сначала весь массив корзины, затем обращаешься только к одному ее элементу, который определен ключом $key — тот элемент, с которым производится действие (добавление, изменение) в данный момент. Но задача — обработать все элементы. Соответственно, необходимо пройти по всему массиву и обработать его:

foreach($cartArray as $cartProduct) { // Запускаем цикл прохода по всем товарам в корзине
	$price = $cartProduct['price']; // Один элемент корзины
}
Следующий важный момент: изменять необходимо оригинальную цену, а не ту, которая в корзине. Пример: один раз изменили цену при достижении 5 шт., пользователь погулял по сайту, в корзине стало 20 шт. — если при втором изменении мы возьмем за основу цену, которая записана в корзине, скидка получится чрезмерной.

Если 2 варианта решения:
1) В options товара в корзине записывать оригинальную цену при добавлении
2) Каждый раз получать оригинальную цену из объекта товара

Второй вариант рациональнее.

switch ($modx->event->name) {
	case 'msOnAddToCart': case 'msOnChangeInCart':

		$cartArray = $cart->get();
		$cartStatus = $cart->status();
		$totalCount = $cartStatus['total_count'];

		if ($totalCount < 5) $coeff = 1;
		elseif ($totalCount < 10) $coeff = 0.8;
		elseif ($totalCount < 20) $coeff = 0.7;
		else $coeff = 0.6;

		foreach ($cartArray as &$cartProduct) {
			if ($product = $modx->getObject('msProduct', $cartProduct['id'])) {
				$cartProduct['price'] = $product->price * $coeff;
			}
		}
		
		$cart->set($cartArray);
		break;

}
«Костыли-сниппеты» — это такие вложенные вызовы. Из-за особенностей работы парсера необходимо избегать подобной вложенности. Либо через чанки (в простых случаях), либо через сниппеты. Если уж хочется использовать логику в шаблонах, смотрите в сторону Fenom — он больше возможностей предоставит.
В классе корзины переопредели 3 метода: get(), status(), clean(). Сниппет вывода корзины сделай свой, удобнее всего скопировать msCart и его изменить.
Сохранение принадлежности товара к определенному контексту в оформленном заказе — самое простое, достаточно при добавлении в корзину передавать эту информацию в options товара, дальше справится штатный механизм.

Фактически, задача решается за несколько часов.