1: | <?php
2: | namespace Opencart\Catalog\Controller\Product;
3: | /**
4: | * Class Product
5: | *
6: | * @package Opencart\Catalog\Controller\Product
7: | */
8: | class Product extends \Opencart\System\Engine\Controller {
9: | /**
10: | * @return ?\Opencart\System\Engine\Action
11: | */
12: | public function index(): ?\Opencart\System\Engine\Action {
13: | $this->load->language('product/product');
14: |
15: | if (isset($this->request->get['product_id'])) {
16: | $product_id = (int)$this->request->get['product_id'];
17: | } else {
18: | $product_id = 0;
19: | }
20: |
21: | $this->load->model('catalog/product');
22: |
23: | $product_info = $this->model_catalog_product->getProduct($product_id);
24: |
25: | if ($product_info) {
26: | $this->document->setTitle($product_info['meta_title']);
27: | $this->document->setDescription($product_info['meta_description']);
28: | $this->document->setKeywords($product_info['meta_keyword']);
29: | $this->document->addLink($this->url->link('product/product', 'language=' . $this->config->get('config_language') . '&product_id=' . $product_id), 'canonical');
30: |
31: | $data['breadcrumbs'] = [];
32: |
33: | $data['breadcrumbs'][] = [
34: | 'text' => $this->language->get('text_home'),
35: | 'href' => $this->url->link('common/home', 'language=' . $this->config->get('config_language'))
36: | ];
37: |
38: | $this->load->model('catalog/category');
39: |
40: | if (isset($this->request->get['path'])) {
41: | $path = '';
42: |
43: | $parts = explode('_', (string)$this->request->get['path']);
44: |
45: | $category_id = (int)array_pop($parts);
46: |
47: | foreach ($parts as $path_id) {
48: | if (!$path) {
49: | $path = $path_id;
50: | } else {
51: | $path .= '_' . $path_id;
52: | }
53: |
54: | $category_info = $this->model_catalog_category->getCategory((int)$path_id);
55: |
56: | if ($category_info) {
57: | $data['breadcrumbs'][] = [
58: | 'text' => $category_info['name'],
59: | 'href' => $this->url->link('product/category', 'language=' . $this->config->get('config_language') . '&path=' . $path)
60: | ];
61: | }
62: | }
63: |
64: | // Set the last category breadcrumb
65: | $category_info = $this->model_catalog_category->getCategory($category_id);
66: |
67: | if ($category_info) {
68: | $url = '';
69: |
70: | if (isset($this->request->get['sort'])) {
71: | $url .= '&sort=' . $this->request->get['sort'];
72: | }
73: |
74: | if (isset($this->request->get['order'])) {
75: | $url .= '&order=' . $this->request->get['order'];
76: | }
77: |
78: | if (isset($this->request->get['page'])) {
79: | $url .= '&page=' . $this->request->get['page'];
80: | }
81: |
82: | if (isset($this->request->get['limit'])) {
83: | $url .= '&limit=' . $this->request->get['limit'];
84: | }
85: |
86: | $data['breadcrumbs'][] = [
87: | 'text' => $category_info['name'],
88: | 'href' => $this->url->link('product/category', 'language=' . $this->config->get('config_language') . '&path=' . $this->request->get['path'] . $url)
89: | ];
90: | }
91: | }
92: |
93: | $this->load->model('catalog/manufacturer');
94: |
95: | if (isset($this->request->get['manufacturer_id'])) {
96: | $data['breadcrumbs'][] = [
97: | 'text' => $this->language->get('text_brand'),
98: | 'href' => $this->url->link('product/manufacturer', 'language=' . $this->config->get('config_language'))
99: | ];
100: |
101: | $url = '';
102: |
103: | if (isset($this->request->get['sort'])) {
104: | $url .= '&sort=' . $this->request->get['sort'];
105: | }
106: |
107: | if (isset($this->request->get['order'])) {
108: | $url .= '&order=' . $this->request->get['order'];
109: | }
110: |
111: | if (isset($this->request->get['page'])) {
112: | $url .= '&page=' . $this->request->get['page'];
113: | }
114: |
115: | if (isset($this->request->get['limit'])) {
116: | $url .= '&limit=' . $this->request->get['limit'];
117: | }
118: |
119: | $manufacturer_info = $this->model_catalog_manufacturer->getManufacturer($this->request->get['manufacturer_id']);
120: |
121: | if ($manufacturer_info) {
122: | $data['breadcrumbs'][] = [
123: | 'text' => $manufacturer_info['name'],
124: | 'href' => $this->url->link('product/manufacturer.info', 'language=' . $this->config->get('config_language') . '&manufacturer_id=' . $this->request->get['manufacturer_id'] . $url)
125: | ];
126: | }
127: | }
128: |
129: | if (isset($this->request->get['search']) || isset($this->request->get['tag'])) {
130: | $url = '';
131: |
132: | if (isset($this->request->get['search'])) {
133: | $url .= '&search=' . $this->request->get['search'];
134: | }
135: |
136: | if (isset($this->request->get['tag'])) {
137: | $url .= '&tag=' . $this->request->get['tag'];
138: | }
139: |
140: | if (isset($this->request->get['description'])) {
141: | $url .= '&description=' . $this->request->get['description'];
142: | }
143: |
144: | if (isset($this->request->get['category_id'])) {
145: | $url .= '&category_id=' . $this->request->get['category_id'];
146: | }
147: |
148: | if (isset($this->request->get['sub_category'])) {
149: | $url .= '&sub_category=' . $this->request->get['sub_category'];
150: | }
151: |
152: | if (isset($this->request->get['sort'])) {
153: | $url .= '&sort=' . $this->request->get['sort'];
154: | }
155: |
156: | if (isset($this->request->get['order'])) {
157: | $url .= '&order=' . $this->request->get['order'];
158: | }
159: |
160: | if (isset($this->request->get['page'])) {
161: | $url .= '&page=' . $this->request->get['page'];
162: | }
163: |
164: | if (isset($this->request->get['limit'])) {
165: | $url .= '&limit=' . $this->request->get['limit'];
166: | }
167: |
168: | $data['breadcrumbs'][] = [
169: | 'text' => $this->language->get('text_search'),
170: | 'href' => $this->url->link('product/search', 'language=' . $this->config->get('config_language') . $url)
171: | ];
172: | }
173: |
174: | $url = '';
175: |
176: | if (isset($this->request->get['path'])) {
177: | $url .= '&path=' . $this->request->get['path'];
178: | }
179: |
180: | if (isset($this->request->get['filter'])) {
181: | $url .= '&filter=' . $this->request->get['filter'];
182: | }
183: |
184: | if (isset($this->request->get['manufacturer_id'])) {
185: | $url .= '&manufacturer_id=' . $this->request->get['manufacturer_id'];
186: | }
187: |
188: | if (isset($this->request->get['search'])) {
189: | $url .= '&search=' . $this->request->get['search'];
190: | }
191: |
192: | if (isset($this->request->get['tag'])) {
193: | $url .= '&tag=' . $this->request->get['tag'];
194: | }
195: |
196: | if (isset($this->request->get['description'])) {
197: | $url .= '&description=' . $this->request->get['description'];
198: | }
199: |
200: | if (isset($this->request->get['category_id'])) {
201: | $url .= '&category_id=' . $this->request->get['category_id'];
202: | }
203: |
204: | if (isset($this->request->get['sub_category'])) {
205: | $url .= '&sub_category=' . $this->request->get['sub_category'];
206: | }
207: |
208: | if (isset($this->request->get['sort'])) {
209: | $url .= '&sort=' . $this->request->get['sort'];
210: | }
211: |
212: | if (isset($this->request->get['order'])) {
213: | $url .= '&order=' . $this->request->get['order'];
214: | }
215: |
216: | if (isset($this->request->get['page'])) {
217: | $url .= '&page=' . $this->request->get['page'];
218: | }
219: |
220: | if (isset($this->request->get['limit'])) {
221: | $url .= '&limit=' . $this->request->get['limit'];
222: | }
223: |
224: | $data['breadcrumbs'][] = [
225: | 'text' => $product_info['name'],
226: | 'href' => $this->url->link('product/product', 'language=' . $this->config->get('config_language') . $url . '&product_id=' . $product_id)
227: | ];
228: |
229: | $this->document->setTitle($product_info['meta_title']);
230: | $this->document->setDescription($product_info['meta_description']);
231: | $this->document->setKeywords($product_info['meta_keyword']);
232: | $this->document->addLink($this->url->link('product/product', 'language=' . $this->config->get('config_language') . '&product_id=' . $product_id), 'canonical');
233: |
234: | $this->document->addScript('catalog/view/javascript/jquery/magnific/jquery.magnific-popup.min.js');
235: | $this->document->addStyle('catalog/view/javascript/jquery/magnific/magnific-popup.css');
236: |
237: | $data['heading_title'] = $product_info['name'];
238: |
239: | $data['text_minimum'] = sprintf($this->language->get('text_minimum'), $product_info['minimum']);
240: | $data['text_login'] = sprintf($this->language->get('text_login'), $this->url->link('account/login', 'language=' . $this->config->get('config_language')), $this->url->link('account/register', 'language=' . $this->config->get('config_language')));
241: | $data['text_reviews'] = sprintf($this->language->get('text_reviews'), (int)$product_info['reviews']);
242: |
243: | $data['tab_review'] = sprintf($this->language->get('tab_review'), $product_info['reviews']);
244: |
245: | $data['error_upload_size'] = sprintf($this->language->get('error_upload_size'), $this->config->get('config_file_max_size'));
246: |
247: | $data['config_file_max_size'] = ((int)$this->config->get('config_file_max_size') * 1024 * 1024);
248: |
249: | $this->session->data['upload_token'] = oc_token(32);
250: |
251: | $data['upload'] = $this->url->link('tool/upload', 'language=' . $this->config->get('config_language') . '&upload_token=' . $this->session->data['upload_token']);
252: |
253: | $data['product_id'] = $product_id;
254: |
255: | $manufacturer_info = $this->model_catalog_manufacturer->getManufacturer($product_info['manufacturer_id']);
256: |
257: | if ($manufacturer_info) {
258: | $data['manufacturer'] = $manufacturer_info['name'];
259: | } else {
260: | $data['manufacturer'] = '';
261: | }
262: |
263: | $data['manufacturers'] = $this->url->link('product/manufacturer.info', 'language=' . $this->config->get('config_language') . '&manufacturer_id=' . $product_info['manufacturer_id']);
264: | $data['model'] = $product_info['model'];
265: | $data['reward'] = $product_info['reward'];
266: | $data['points'] = $product_info['points'];
267: | $data['description'] = html_entity_decode($product_info['description'], ENT_QUOTES, 'UTF-8');
268: |
269: | if ($product_info['quantity'] <= 0) {
270: | $this->load->model('localisation/stock_status');
271: |
272: | $stock_status_info = $this->model_localisation_stock_status->getStockStatus($product_info['stock_status_id']);
273: |
274: | if ($stock_status_info) {
275: | $data['stock'] = $stock_status_info['name'];
276: | } else {
277: | $data['stock'] = '';
278: | }
279: | } elseif ($this->config->get('config_stock_display')) {
280: | $data['stock'] = $product_info['quantity'];
281: | } else {
282: | $data['stock'] = $this->language->get('text_instock');
283: | }
284: |
285: | $data['rating'] = (int)$product_info['rating'];
286: | $data['review_status'] = (int)$this->config->get('config_review_status');
287: | $data['review'] = $this->load->controller('product/review');
288: |
289: | $data['wishlist_add'] = $this->url->link('account/wishlist.add', 'language=' . $this->config->get('config_language'));
290: | $data['compare_add'] = $this->url->link('product/compare.add', 'language=' . $this->config->get('config_language'));
291: |
292: | $this->load->model('tool/image');
293: |
294: | if ($product_info['image'] && is_file(DIR_IMAGE . html_entity_decode($product_info['image'], ENT_QUOTES, 'UTF-8'))) {
295: | $data['popup'] = $this->model_tool_image->resize($product_info['image'], $this->config->get('config_image_popup_width'), $this->config->get('config_image_popup_height'));
296: | $data['thumb'] = $this->model_tool_image->resize($product_info['image'], $this->config->get('config_image_thumb_width'), $this->config->get('config_image_thumb_height'));
297: | } else {
298: | $data['popup'] = '';
299: | $data['thumb'] = '';
300: | }
301: |
302: | $data['images'] = [];
303: |
304: | $results = $this->model_catalog_product->getImages($product_id);
305: |
306: | foreach ($results as $result) {
307: | if ($result['image'] && is_file(DIR_IMAGE . html_entity_decode($result['image'], ENT_QUOTES, 'UTF-8'))) {
308: | $data['images'][] = [
309: | 'popup' => $this->model_tool_image->resize($result['image'], $this->config->get('config_image_popup_width'), $this->config->get('config_image_popup_height')),
310: | 'thumb' => $this->model_tool_image->resize($result['image'], $this->config->get('config_image_additional_width'), $this->config->get('config_image_additional_height'))
311: | ];
312: | }
313: | }
314: |
315: | if ($this->customer->isLogged() || !$this->config->get('config_customer_price')) {
316: | $data['price'] = $this->currency->format($this->tax->calculate($product_info['price'], $product_info['tax_class_id'], $this->config->get('config_tax')), $this->session->data['currency']);
317: | } else {
318: | $data['price'] = false;
319: | }
320: |
321: | if ((float)$product_info['special']) {
322: | $data['special'] = $this->currency->format($this->tax->calculate($product_info['special'], $product_info['tax_class_id'], $this->config->get('config_tax')), $this->session->data['currency']);
323: | } else {
324: | $data['special'] = false;
325: | }
326: |
327: | if ($this->config->get('config_tax')) {
328: | $data['tax'] = $this->currency->format((float)$product_info['special'] ? $product_info['special'] : $product_info['price'], $this->session->data['currency']);
329: | } else {
330: | $data['tax'] = false;
331: | }
332: |
333: | $discounts = $this->model_catalog_product->getDiscounts($product_id);
334: |
335: | $data['discounts'] = [];
336: |
337: | if ($this->customer->isLogged() || !$this->config->get('config_customer_price')) {
338: | foreach ($discounts as $discount) {
339: | $data['discounts'][] = [
340: | 'quantity' => $discount['quantity'],
341: | 'price' => $this->currency->format($this->tax->calculate($discount['price'], $product_info['tax_class_id'], $this->config->get('config_tax')), $this->session->data['currency'])
342: | ];
343: | }
344: | }
345: |
346: | $data['options'] = [];
347: |
348: | // Check if product is variant
349: | if ($product_info['master_id']) {
350: | $master_id = (int)$product_info['master_id'];
351: | } else {
352: | $master_id = (int)$this->request->get['product_id'];
353: | }
354: |
355: | $product_options = $this->model_catalog_product->getOptions($master_id);
356: |
357: | foreach ($product_options as $option) {
358: | if ((int)$this->request->get['product_id'] && !isset($product_info['override']['variant'][$option['product_option_id']])) {
359: | $product_option_value_data = [];
360: |
361: | foreach ($option['product_option_value'] as $option_value) {
362: | if (!$option_value['subtract'] || ($option_value['quantity'] > 0)) {
363: | if ((($this->config->get('config_customer_price') && $this->customer->isLogged()) || !$this->config->get('config_customer_price')) && (float)$option_value['price']) {
364: | $price = $this->currency->format($this->tax->calculate($option_value['price'], $product_info['tax_class_id'], $this->config->get('config_tax') ? 'P' : false), $this->session->data['currency']);
365: | } else {
366: | $price = false;
367: | }
368: |
369: | if ($option_value['image'] && is_file(DIR_IMAGE . html_entity_decode($option_value['image'], ENT_QUOTES, 'UTF-8'))) {
370: | $image = $option_value['image'];
371: | } else {
372: | $image = '';
373: | }
374: |
375: | $product_option_value_data[] = [
376: | 'product_option_value_id' => $option_value['product_option_value_id'],
377: | 'option_value_id' => $option_value['option_value_id'],
378: | 'name' => $option_value['name'],
379: | 'image' => $this->model_tool_image->resize($image, 50, 50),
380: | 'price' => $price,
381: | 'price_prefix' => $option_value['price_prefix']
382: | ];
383: | }
384: | }
385: |
386: | $data['options'][] = [
387: | 'product_option_id' => $option['product_option_id'],
388: | 'product_option_value' => $product_option_value_data,
389: | 'option_id' => $option['option_id'],
390: | 'name' => $option['name'],
391: | 'type' => $option['type'],
392: | 'value' => $option['value'],
393: | 'required' => $option['required']
394: | ];
395: | }
396: | }
397: |
398: | // Subscriptions
399: | $data['subscription_plans'] = [];
400: |
401: | $results = $this->model_catalog_product->getSubscriptions($product_id);
402: |
403: | foreach ($results as $result) {
404: | $description = '';
405: |
406: | if ($result['trial_status']) {
407: | $trial_price = $this->currency->format($this->tax->calculate($result['trial_price'], $product_info['tax_class_id'], $this->config->get('config_tax')), $this->session->data['currency']);
408: | $trial_cycle = $result['trial_cycle'];
409: | $trial_frequency = $this->language->get('text_' . $result['trial_frequency']);
410: | $trial_duration = $result['trial_duration'];
411: |
412: | $description .= sprintf($this->language->get('text_subscription_trial'), $trial_price, $trial_cycle, $trial_frequency, $trial_duration);
413: | }
414: |
415: | $price = $this->currency->format($this->tax->calculate($result['price'], $product_info['tax_class_id'], $this->config->get('config_tax')), $this->session->data['currency']);
416: | $cycle = $result['cycle'];
417: | $frequency = $this->language->get('text_' . $result['frequency']);
418: | $duration = $result['duration'];
419: |
420: | if ($duration) {
421: | $description .= sprintf($this->language->get('text_subscription_duration'), $price, $cycle, $frequency, $duration);
422: | } else {
423: | $description .= sprintf($this->language->get('text_subscription_cancel'), $price, $cycle, $frequency);
424: | }
425: |
426: | $data['subscription_plans'][] = [
427: | 'subscription_plan_id' => $result['subscription_plan_id'],
428: | 'name' => $result['name'],
429: | 'description' => $description
430: | ];
431: | }
432: |
433: | if ($product_info['minimum']) {
434: | $data['minimum'] = $product_info['minimum'];
435: | } else {
436: | $data['minimum'] = 1;
437: | }
438: |
439: | $data['share'] = $this->url->link('product/product', 'language=' . $this->config->get('config_language') . '&product_id=' . (int)$this->request->get['product_id']);
440: |
441: | $data['attribute_groups'] = $this->model_catalog_product->getAttributes($product_id);
442: |
443: | $data['products'] = [];
444: |
445: | $results = $this->model_catalog_product->getRelated($product_id);
446: |
447: | foreach ($results as $result) {
448: | $description = trim(strip_tags(html_entity_decode($result['description'], ENT_QUOTES, 'UTF-8')));
449: |
450: | if (oc_strlen($description) > $this->config->get('config_product_description_length')) {
451: | $description = oc_substr($description, 0, $this->config->get('config_product_description_length')) . '..';
452: | }
453: |
454: | if ($result['image'] && is_file(DIR_IMAGE . html_entity_decode($result['image'], ENT_QUOTES, 'UTF-8'))) {
455: | $image = $result['image'];
456: | } else {
457: | $image = 'placeholder.png';
458: | }
459: |
460: | if ($this->customer->isLogged() || !$this->config->get('config_customer_price')) {
461: | $price = $this->currency->format($this->tax->calculate($result['price'], $result['tax_class_id'], $this->config->get('config_tax')), $this->session->data['currency']);
462: | } else {
463: | $price = false;
464: | }
465: |
466: | if ((float)$result['special']) {
467: | $special = $this->currency->format($this->tax->calculate($result['special'], $result['tax_class_id'], $this->config->get('config_tax')), $this->session->data['currency']);
468: | } else {
469: | $special = false;
470: | }
471: |
472: | if ($this->config->get('config_tax')) {
473: | $tax = $this->currency->format((float)$result['special'] ? $result['special'] : $result['price'], $this->session->data['currency']);
474: | } else {
475: | $tax = false;
476: | }
477: |
478: | $product_data = [
479: | 'product_id' => $result['product_id'],
480: | 'thumb' => $this->model_tool_image->resize($image, $this->config->get('config_image_related_width'), $this->config->get('config_image_related_height')),
481: | 'name' => $result['name'],
482: | 'description' => $description,
483: | 'price' => $price,
484: | 'special' => $special,
485: | 'tax' => $tax,
486: | 'minimum' => $result['minimum'] > 0 ? $result['minimum'] : 1,
487: | 'rating' => $result['rating'],
488: | 'href' => $this->url->link('product/product', 'language=' . $this->config->get('config_language') . '&product_id=' . $result['product_id'])
489: | ];
490: |
491: | $data['products'][] = $this->load->controller('product/thumb', $product_data);
492: | }
493: |
494: | $data['tags'] = [];
495: |
496: | if ($product_info['tag']) {
497: | $tags = explode(',', $product_info['tag']);
498: |
499: | foreach ($tags as $tag) {
500: | $data['tags'][] = [
501: | 'tag' => trim($tag),
502: | 'href' => $this->url->link('product/search', 'language=' . $this->config->get('config_language') . '&tag=' . trim($tag))
503: | ];
504: | }
505: | }
506: |
507: | if ($this->config->get('config_product_report_status')) {
508: | $this->model_catalog_product->addReport($this->request->get['product_id'], $this->request->server['REMOTE_ADDR']);
509: | }
510: |
511: | $data['language'] = $this->config->get('config_language');
512: |
513: | $data['column_left'] = $this->load->controller('common/column_left');
514: | $data['column_right'] = $this->load->controller('common/column_right');
515: | $data['content_top'] = $this->load->controller('common/content_top');
516: | $data['content_bottom'] = $this->load->controller('common/content_bottom');
517: | $data['footer'] = $this->load->controller('common/footer');
518: | $data['header'] = $this->load->controller('common/header');
519: |
520: | $this->response->setOutput($this->load->view('product/product', $data));
521: | } else {
522: | return new \Opencart\System\Engine\Action('error/not_found');
523: | }
524: |
525: | return null;
526: | }
527: | }
528: |

OpenCart API API documentation generated by ApiGen dev-master