OK, para apontar a direção certa, é assim que eu faria isso:
1. renderização de entrada oculta
Como você deve saber, em um
catalog/view/theme/default/template/product/product.php
há solicitação AJAX para adicionar produto ao carrinho:$('#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',
// ...
});
});
Se você olhar nos
data
parâmetro Você verá que todas as entradas, seleções, áreas de texto etc. presentes em um .product-info
div são preenchidos e postados no PHP. Portanto, eu renderizaria a entrada oculta com valor de preço personalizado nesse
.product-info
div para não precisar modificar a solicitação AJAX. Digamos que o nome dessa entrada seja custom_price
. 2. O
checkout/cart/add
Abra
catalog/controller/checkout/cart.php
e procure por add
método. Aqui toda a magia deve ser feita. Após esta parte do código: if (isset($this->request->post['option'])) {
$option = array_filter($this->request->post['option']);
} else {
$option = array();
}
Eu adicionaria isso:
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;
}
Implemente o
isCustomPriceValid()
método para atender aos seus requisitos... e avançar para a última edição aqui - altere esta linha:$this->cart->add($this->request->post['product_id'], $quantity, $option);
para:
$this->cart->add($this->request->post['product_id'], $quantity, $option, $custom_price);
3. O carrinho
Agora abra este arquivo:
system/library/cart.php
e novamente procure por add
método. Você teria que alterar a definição do método para este:public function add($product_id, $qty = 1, $option = array(), $custom_price = false) {
Antes da última linha de código dentro deste método, adicione outra:
(este código foi editado devido ao comentário do OP)
// ...
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
}
A última edição deve estar dentro do método
getProducts()
pois este está carregando todos os dados do banco de dados e os encaminha para outros controladores para fins de exibição. Agora não sei se o seu preço personalizado deve substituir o preço + preço das opções ou apenas o preço, portanto, o preço das opções será adicionado a ele, então eu ficaria com a segunda opção, pois é mais descritiva e a primeira opção pode ser facilmente derivado do meu exemplo.
Procure a linha
$price = $product_query->row['price'];
e logo após adicionar
if(isset($this->session->data['cart']['custom_price'][$key])) {
$price = $this->session->data['cart']['custom_price'][$key];
}
Agora, o preço deve ser substituído pelo personalizado. Verifique ainda se o preço do produto é definido posteriormente como:
$this->data[$key] = array(
// ...
'price' => ($price + $option_price),
// ...
);
Portanto, se você quiser substituir o preço inteiro pelo personalizado, adicione essa condição logo após esse array como este (em vez de depois de
$price = ...;
):if(isset($this->session->data['cart']['custom_price'][$key])) {
$this->data[$key]['price'] = $this->session->data['cart']['custom_price'][$key];
}
Deve ser isso. Não testei o código, pode ou não funcionar com pequenas modificações. Eu estava trabalhando com OC 1.5.5.1. Isso só deve apontar para a direção certa (enquanto acredita que o final não está tão longe).
Apreciar!