Добре, за да ви насоча правилната посока, ето как ще направя това:
1. скрит входен рендер
Както може би знаете, в catalog/view/theme/default/template/product/product.php
има AJAX заявка за добавяне на продукт в количката:
$('#button-cart').bind('click', function() {
$.ajax({
url: 'index.php?route=checkout/cart/add',
type: 'post',
data: $('.product-info input[type=\'text\'], .product-info input[type=\'hidden\'], .product-info input[type=\'radio\']:checked, .product-info input[type=\'checkbox\']:checked, .product-info select, .product-info textarea'),
dataType: 'json',
// ...
});
});
Ако погледнете data
параметър Ще видите, че всички входове, селекти, текстови области и т.н. присъстват в .product-info
div се попълват и публикуват в PHP.
Затова бих изобразил скрития вход със стойност на персонализирана цена в този .product-info
div, за да не се налага изобщо да променяте заявката на AJAX. Да кажем, че името на този вход ще бъде custom_price
.
2. checkout/cart/add
Отворете catalog/controller/checkout/cart.php
и потърсете add
метод. Тук трябва да се направи цялата магия. След тази част от кода:
if (isset($this->request->post['option'])) {
$option = array_filter($this->request->post['option']);
} else {
$option = array();
}
Бих добавил това:
if(isset($this->request->post['custom_price']) && $this->isCustomPriceValid($this->request->post['custom_price'])) {
$custom_price = $this->request->post['custom_price'];
} else {
$custom_price = false;
}
Реализирайте isCustomPriceValid()
метод, за да отговори на вашите изисквания... и преминете към последната редакция тук - променете този ред:
$this->cart->add($this->request->post['product_id'], $quantity, $option);
до:
$this->cart->add($this->request->post['product_id'], $quantity, $option, $custom_price);
3. Количката
Сега отворете този файл:system/library/cart.php
и отново потърсете add
метод. Ще трябва да промените дефиницията на метода на тази:
public function add($product_id, $qty = 1, $option = array(), $custom_price = false) {
Преди последния ред код в този метод добавете още един:
(този код е редактиран поради коментара от ОП)
// ...
if($custom_price) {
if(!isset($this->session->data['cart']['custom_price'])) {
$this->session->data['cart']['custom_price'] = array();
}
$this->session->data['cart']['custom_price'][$key] = $custom_price;
}
$this->data = array(); // <- last line
}
Последната редакция трябва да бъде в метода getProducts()
тъй като този зарежда всички данни от БД и ги препраща към други контролери за показване.
Сега не знам дали вашата персонализирана цена трябва да замести цената + цената на опциите или само цената, така че цената на опциите ще бъде добавена към нея, така че бих се придържал към втория избор, тъй като е по-описателен и първият избор може лесно се извлича от моя пример.
Потърсете реда
$price = $product_query->row['price'];
и веднага след добавяне
if(isset($this->session->data['cart']['custom_price'][$key])) {
$price = $this->session->data['cart']['custom_price'][$key];
}
Сега цената трябва да бъде презаписана с персонализираната. Проверете допълнително дали цената за продукта по-късно е зададена като:
$this->data[$key] = array(
// ...
'price' => ($price + $option_price),
// ...
);
Така че, ако искате да презапишете цялата цена с персонализираната, добавете това условие веднага след този масив по този начин (вместо след $price = ...;
):
if(isset($this->session->data['cart']['custom_price'][$key])) {
$this->data[$key]['price'] = $this->session->data['cart']['custom_price'][$key];
}
Това трябва да бъде. Не съм тествал кода, може да работи или да не работи с леки модификации. Работех с OC 1.5.5.1. Това трябва само да ви насочи към правилната посока (въпреки че вярвате, че финалът не е толкова далеч).
Насладете се!