问题描述
如何在 opencart 3 的标准(基本)模块中显示产品选项
我在文件中添加了代码:modification\catalog\controller\extension\module\featured.PHP
代码:
$options = array();
foreach ($this->model_catalog_product->getProductOptions($result['product_id']) as $option) {
if($option['required']){
$product_option_value_data = array();
foreach ($option['product_option_value'] as $option_value) {
if (!$option_value['subtract'] || ($option_value['quantity'] >= 0)) {
$product_option_value_data[] = array(
'product_option_value_id' => $option_value['product_option_value_id'],'option_value_id' => $option_value['option_value_id'],'name' => $option_value['name'],'image' => $this->model_tool_image->resize($option_value['image'],50,50),'quantity' => $option_value['quantity'],'price_prefix' => $option_value['price_prefix']
);
}
}
$options[] = array(
'product_option_id' => $option['product_option_id'],'product_option_value' => $product_option_value_data,'option_id' => $option['option_id'],'name' => $option['name'],'type' => $option['type'],'value' => $option['value'],'required' => $option['required']
);
}
}
还添加了:
$data['products'][] = array(
'options' => $options,
对于文件中的输出:template\extension\module\featured.twig
{% if product.options %}
{% for option in product.options %}
{% if option.type == 'radio' %}
<div class="groupOptionWrap {% if option.required %} required {% endif %}">
{#<label class="control-label">
{{ option.name }}
</label>#}
<div id="input-option{{ option.product_option_id }}" class='groupOptionElements'>
{% for option_value in option.product_option_value %}
{% if option_value.quantity == "0" %}
<div class="groupOption groupOptiondisable">
{{ option_value.name }}
</div>
{% else %}
<div class="groupOption">
{{ option_value.name }}
</div>
{% endif %}
{% endfor %}
</div>
</div>
{% endif %}
{% endfor %}
{% endif %}
但是没用
<?PHP
class ControllerExtensionModuleFeatured extends Controller {
public function index($setting) {
$this->load->language('extension/module/notify_when_available');
$data['text_out_of_stock'] = $this->language->get('text_out_of_stock');
$data['out_of_stock_show'] = $this->config->get('module_notify_when_available_stock');
$data['out_of_stock_notify'] = $this->config->get('module_notify_when_available_notify');
$this->load->language('extension/module/featured');
$this->load->model('catalog/product');
$this->load->model('tool/image');
$data['products'] = array();
if (!$setting['limit']) {
$setting['limit'] = 4;
}
if (!empty($setting['product'])) {
$lang = $this->config->get('config_language_id');
$title = isset($setting['titles']['title'.$lang]) && $setting['titles']['title'.$lang] ? $setting['titles']['title'.$lang] : '';
if (isset($title) && $title) {
$data['heading_title'] = $title;
}
if (isset($setting['shuffle']) && $setting['shuffle']) {
shuffle($setting['product']);
}
$products = array_slice($setting['product'],(int)$setting['limit']);
foreach ($products as $product_id) {
$product_info = $this->model_catalog_product->getProduct($product_id);
if ($product_info) {
if ($product_info['image']) {
$image = $this->model_tool_image->resize($product_info['image'],$setting['width'],$setting['height']);
} else {
$image = $this->model_tool_image->resize('placeholder.png',$setting['height']);
}
if ($this->customer->isLogged() || !$this->config->get('config_customer_price')) {
$price = $this->currency->format($this->tax->calculate($product_info['price'],$product_info['tax_class_id'],$this->config->get('config_tax')),$this->session->data['currency']);
$data['priceInt'] = $this->tax->calculate($product_info['price'],$this->config->get('config_tax'));
} else {
$price = false;
}
$specialSavings =0;
if ((float)$product_info['special']) {
$special = $this->currency->format($this->tax->calculate($product_info['special'],$this->session->data['currency']);
$data['specialInt'] = $this->tax->calculate($product_info['special'],$this->config->get('config_tax'));
$data['specialSavings'] = round((($data['priceInt']-$data['specialInt'])/$data['priceInt'])*100,2);
$specialSavings = $data['specialSavings'];
} else {
$special = false;
}
if ($this->config->get('config_tax')) {
$tax = $this->currency->format((float)$product_info['special'] ? $product_info['special'] : $product_info['price'],$this->session->data['currency']);
} else {
$tax = false;
}
if ($this->config->get('config_review_status')) {
$rating = $product_info['rating'];
} else {
$rating = false;
}
$options = array();
foreach ($this->model_catalog_product->getProductOptions($result['product_id']) as $option) {
if($option['required']){
$product_option_value_data = array();
foreach ($option['product_option_value'] as $option_value) {
if (!$option_value['subtract'] || ($option_value['quantity'] >= 0)) {
$product_option_value_data[] = array(
'product_option_value_id' => $option_value['product_option_value_id'],'price_prefix' => $option_value['price_prefix']
);
}
}
$options[] = array(
'product_option_id' => $option['product_option_id'],'required' => $option['required']
);
}
}
$data['products'][] = array(
'product_id' => $product_info['product_id'],'quantity' => $result['quantity'],'quantity' => $product_info['quantity'],'quantity' => isset($result['quantity']) ? $result['quantity'] : (isset($product_info['quantity']) ? $product_info['quantity'] : 1),'attribute_groups' => $this->model_catalog_product->getProductAttributes($product_info['product_id']),'thumb' => $image,'name' => $product_info['name'],'description' => utf8_substr(strip_tags(html_entity_decode($product_info['description'],ENT_QUOTES,'UTF-8')),$this->config->get('theme_' . $this->config->get('config_theme') . '_product_description_length')) . '..','price' => $price,'special' => $special,'specialSavings' => $specialSavings,'tax' => $tax,'rating' => $rating,'href' => $this->url->link('product/product','product_id=' . $product_info['product_id'])
);
}
}
}
if ($data['products']) {
return $this->load->view('extension/module/featured',$data);
}
}
}
此代码的新变体:
<?PHP
class ControllerExtensionModuleFeatured extends Controller {
public function index($setting) {
$this->load->language('extension/module/notify_when_available');
$data['text_out_of_stock'] = $this->language->get('text_out_of_stock');
$data['out_of_stock_show'] = $this->config->get('module_notify_when_available_stock');
$data['out_of_stock_notify'] = $this->config->get('module_notify_when_available_notify');
$this->load->language('extension/module/featured');
$this->load->model('catalog/product');
$this->load->model('tool/image');
$data['products'] = array();
if (!$setting['limit']) {
$setting['limit'] = 4;
}
if (!empty($setting['product'])) {
$lang = $this->config->get('config_language_id');
$title = isset($setting['titles']['title'.$lang]) && $setting['titles']['title'.$lang] ? $setting['titles']['title'.$lang] : '';
if (isset($title) && $title) {
$data['heading_title'] = $title;
}
if (isset($setting['shuffle']) && $setting['shuffle']) {
shuffle($setting['product']);
}
$products = array_slice($setting['product'],(int)$setting['limit']);
foreach ($products as $product_id) {
$product_info = $this->model_catalog_product->getProduct($product_id);
if ($product_info) {
if ($product_info['image']) {
$image = $this->model_tool_image->resize($product_info['image'],$setting['height']);
} else {
$image = $this->model_tool_image->resize('placeholder.png',$setting['height']);
}
if ($this->customer->isLogged() || !$this->config->get('config_customer_price')) {
$price = $this->currency->format($this->tax->calculate($product_info['price'],$this->session->data['currency']);
$data['priceInt'] = $this->tax->calculate($product_info['price'],$this->config->get('config_tax'));
} else {
$price = false;
}
$specialSavings =0;
if ((float)$product_info['special']) {
$special = $this->currency->format($this->tax->calculate($product_info['special'],$this->session->data['currency']);
$data['specialInt'] = $this->tax->calculate($product_info['special'],$this->config->get('config_tax'));
$data['specialSavings'] = round((($data['priceInt']-$data['specialInt'])/$data['priceInt'])*100,2);
$specialSavings = $data['specialSavings'];
} else {
$special = false;
}
if ($this->config->get('config_tax')) {
$tax = $this->currency->format((float)$product_info['special'] ? $product_info['special'] : $product_info['price'],$this->session->data['currency']);
} else {
$tax = false;
}
if ($this->config->get('config_review_status')) {
$rating = $product_info['rating'];
} else {
$rating = false;
}
$options = array();
foreach ($this->model_catalog_product->getProductOptions($result['product_id']) as $option) {
$options = [];
if($option['required']){
$product_option_value_data = array();
foreach ($option['product_option_value'] as $option_value) {
if (!$option_value['subtract'] || ($option_value['quantity'] >= 0)) {
$product_option_value_data[] = array(
'product_option_value_id' => $option_value['product_option_value_id'],'price_prefix' => $option_value['price_prefix']
);
}
}
$options[] = array(
'product_option_id' => $option['product_option_id'],'required' => $option['required']
);
foreach($data['products'] as &$product) {
if ($product['id'] == $result['product_id']) {
$product['options'] = $options;
break;
}
}
}
}
$data['products'][] = array(
'product_id' => $product_info['product_id'],'quantity' => $result['quantity'],'quantity' => $product_info['quantity'],'quantity' => isset($result['quantity']) ? $result['quantity'] : (isset($product_info['quantity']) ? $product_info['quantity'] : 1),'attribute_groups' => $this->model_catalog_product->getProductAttributes($product_info['product_id']),'thumb' => $image,'name' => $product_info['name'],'description' => utf8_substr(strip_tags(html_entity_decode($product_info['description'],'price' => $price,'special' => $special,'specialSavings' => $specialSavings,'tax' => $tax,'rating' => $rating,'href' => $this->url->link('product/product','product_id=' . $product_info['product_id']),'options' => $options,);
}
}
}
if ($data['products']) {
return $this->load->view('extension/module/featured',$data);
}
}
}
解决方法
以下行没有意义,这里您只是将所有选项附加到 products
数组的末尾,而不会将属性 options
附加到任何产品
$data['products'][] = [
'options' => $options,]
要么您必须按产品 ID 在 options
数组中对您的选项进行分组,要么通过遍历产品将选项设置为更正 product
- 将选项分组
<?php
if (!isset($options[$result['product_id']])) $options[$result['product_id']] = [];
$options[$result['product_id']][] = array(
'product_option_id' => $option['product_option_id'],'product_option_value' => $product_option_value_data,'option_id' => $option['option_id'],'name' => $option['name'],'type' => $option['type'],'value' => $option['value'],'required' => $option['required']
);
然后您将 options
变量传递给视图,您可以通过执行以下操作访问 twig
中的选项
{% if options[product.id]|default([]) %}
{% for option in options[product.id] %}
{# do stuff #}
{% endfor %}
{% endfor %}
- 为正确的产品分配选项
<?php
foreach ($this->model_catalog_product->getProductOptions($result['product_id']) as $option) {
$options = [];
/** fetch options **/
/** fetch options **/
/** fetch options **/
foreach($data['products'] as &$product) {
if ($product['id'] == $result['product_id']) {
$product['options'] = $options;
break;
}
}
}
执行此操作后,您确实可以像在当前代码段中那样访问选项
{% if product.options|default([]) %}
{% for option in product.options %}
{# do stuff #}
{% endfor %}
{% endif %}
请注意,选项 2 纯粹是关于如何执行此操作的示例,因为您没有指定 $result
或 $data['products']
的来源,我只是试了一下
编辑
正如您现在发布的完整代码一样,选择选项 2 将是更理想的解决方案。
在您发布的代码中,您正在填充 $data['products']
数组 (#110
),这里您只需要附加您创建的 options
数组,例如
$data['products'][] = array(
'product_id' => $product_info['product_id'],'quantity' => $result['quantity'],'quantity' => $product_info['quantity'],'quantity' => isset($result['quantity']) ? $result['quantity'] : (isset($product_info['quantity']) ? $product_info['quantity'] : 1),'attribute_groups' => $this->model_catalog_product->getProductAttributes($product_info['product_id']),'thumb' => $image,'name' => $product_info['name'],'description' => utf8_substr(strip_tags(html_entity_decode($product_info['description'],ENT_QUOTES,'UTF-8')),$this->config->get('theme_' . $this->config->get('config_theme') . '_product_description_length')) . '..','price' => $price,'special' => $special,'specialSavings' => $specialSavings,'tax' => $tax,'rating' => $rating,'href' => $this->url->link('product/product','product_id=' . $product_info['product_id']),'options' => $options,);