1: <?php
2: namespace Opencart\Admin\Controller\Catalog;
3: /**
4: * Class Category
5: *
6: * @package Opencart\Admin\Controller\Catalog
7: */
8: class Category extends \Opencart\System\Engine\Controller {
9: /**
10: * Index
11: *
12: * @return void
13: */
14: public function index(): void {
15: $this->load->language('catalog/category');
16:
17: $this->document->setTitle($this->language->get('heading_title'));
18:
19: $url = '';
20:
21: if (isset($this->request->get['sort'])) {
22: $url .= '&sort=' . $this->request->get['sort'];
23: }
24:
25: if (isset($this->request->get['order'])) {
26: $url .= '&order=' . $this->request->get['order'];
27: }
28:
29: if (isset($this->request->get['page'])) {
30: $url .= '&page=' . $this->request->get['page'];
31: }
32:
33: $data['breadcrumbs'] = [];
34:
35: $data['breadcrumbs'][] = [
36: 'text' => $this->language->get('text_home'),
37: 'href' => $this->url->link('common/dashboard', 'user_token=' . $this->session->data['user_token'])
38: ];
39:
40: $data['breadcrumbs'][] = [
41: 'text' => $this->language->get('heading_title'),
42: 'href' => $this->url->link('catalog/category', 'user_token=' . $this->session->data['user_token'] . $url)
43: ];
44:
45: $data['repair'] = $this->url->link('catalog/category.repair', 'user_token=' . $this->session->data['user_token']);
46: $data['add'] = $this->url->link('catalog/category.form', 'user_token=' . $this->session->data['user_token'] . $url);
47: $data['delete'] = $this->url->link('catalog/category.delete', 'user_token=' . $this->session->data['user_token']);
48:
49: $data['list'] = $this->controller_catalog_category->getList();
50:
51: $data['user_token'] = $this->session->data['user_token'];
52:
53: $data['header'] = $this->load->controller('common/header');
54: $data['column_left'] = $this->load->controller('common/column_left');
55: $data['footer'] = $this->load->controller('common/footer');
56:
57: $this->response->setOutput($this->load->view('catalog/category', $data));
58: }
59:
60: /**
61: * List
62: *
63: * @return void
64: */
65: public function list(): void {
66: $this->load->language('catalog/category');
67:
68: $this->response->setOutput($this->controller_catalog_category->getList());
69: }
70:
71: /**
72: * Get List
73: *
74: * @return string
75: */
76: protected function getList(): string {
77: if (isset($this->request->get['sort'])) {
78: $sort = (string)$this->request->get['sort'];
79: } else {
80: $sort = 'name';
81: }
82:
83: if (isset($this->request->get['order'])) {
84: $order = (string)$this->request->get['order'];
85: } else {
86: $order = 'ASC';
87: }
88:
89: if (isset($this->request->get['page'])) {
90: $page = (int)$this->request->get['page'];
91: } else {
92: $page = 1;
93: }
94:
95: $url = '';
96:
97: if (isset($this->request->get['sort'])) {
98: $url .= '&sort=' . $this->request->get['sort'];
99: }
100:
101: if (isset($this->request->get['order'])) {
102: $url .= '&order=' . $this->request->get['order'];
103: }
104:
105: if (isset($this->request->get['page'])) {
106: $url .= '&page=' . $this->request->get['page'];
107: }
108:
109: $data['action'] = $this->url->link('catalog/category.list', 'user_token=' . $this->session->data['user_token'] . $url);
110:
111: $data['categories'] = [];
112:
113: $filter_data = [
114: 'sort' => $sort,
115: 'order' => $order,
116: 'start' => ($page - 1) * $this->config->get('config_pagination_admin'),
117: 'limit' => $this->config->get('config_pagination_admin')
118: ];
119:
120: $this->load->model('catalog/category');
121:
122: $results = $this->model_catalog_category->getCategories($filter_data);
123:
124: foreach ($results as $result) {
125: $data['categories'][] = [
126: 'category_id' => $result['category_id'],
127: 'name' => $result['name'],
128: 'status' => $result['status'],
129: 'sort_order' => $result['sort_order'],
130: 'edit' => $this->url->link('catalog/category.form', 'user_token=' . $this->session->data['user_token'] . '&category_id=' . $result['category_id'] . $url)
131: ];
132: }
133:
134: $url = '';
135:
136: if ($order == 'ASC') {
137: $url .= '&order=DESC';
138: } else {
139: $url .= '&order=ASC';
140: }
141:
142: $data['sort_name'] = $this->url->link('catalog/category.list', 'user_token=' . $this->session->data['user_token'] . '&sort=name' . $url);
143: $data['sort_sort_order'] = $this->url->link('catalog/category.list', 'user_token=' . $this->session->data['user_token'] . '&sort=sort_order' . $url);
144:
145: $url = '';
146:
147: if (isset($this->request->get['sort'])) {
148: $url .= '&sort=' . $this->request->get['sort'];
149: }
150:
151: if (isset($this->request->get['order'])) {
152: $url .= '&order=' . $this->request->get['order'];
153: }
154:
155: $category_total = $this->model_catalog_category->getTotalCategories();
156:
157: $data['pagination'] = $this->load->controller('common/pagination', [
158: 'total' => $category_total,
159: 'page' => $page,
160: 'limit' => $this->config->get('config_pagination_admin'),
161: 'url' => $this->url->link('catalog/category.list', 'user_token=' . $this->session->data['user_token'] . $url . '&page={page}')
162: ]);
163:
164: $data['results'] = sprintf($this->language->get('text_pagination'), ($category_total) ? (($page - 1) * $this->config->get('config_pagination_admin')) + 1 : 0, ((($page - 1) * $this->config->get('config_pagination_admin')) > ($category_total - $this->config->get('config_pagination_admin'))) ? $category_total : ((($page - 1) * $this->config->get('config_pagination_admin')) + $this->config->get('config_pagination_admin')), $category_total, ceil($category_total / $this->config->get('config_pagination_admin')));
165:
166: $data['sort'] = $sort;
167: $data['order'] = $order;
168:
169: return $this->load->view('catalog/category_list', $data);
170: }
171:
172: /**
173: * Form
174: *
175: * @return void
176: */
177: public function form(): void {
178: $this->load->language('catalog/category');
179:
180: $this->document->setTitle($this->language->get('heading_title'));
181:
182: $this->document->addScript('view/javascript/ckeditor/ckeditor.js');
183: $this->document->addScript('view/javascript/ckeditor/adapters/jquery.js');
184:
185: $data['text_form'] = !isset($this->request->get['category_id']) ? $this->language->get('text_add') : $this->language->get('text_edit');
186:
187: $url = '';
188:
189: if (isset($this->request->get['sort'])) {
190: $url .= '&sort=' . $this->request->get['sort'];
191: }
192:
193: if (isset($this->request->get['order'])) {
194: $url .= '&order=' . $this->request->get['order'];
195: }
196:
197: if (isset($this->request->get['page'])) {
198: $url .= '&page=' . $this->request->get['page'];
199: }
200:
201: $data['breadcrumbs'] = [];
202:
203: $data['breadcrumbs'][] = [
204: 'text' => $this->language->get('text_home'),
205: 'href' => $this->url->link('common/dashboard', 'user_token=' . $this->session->data['user_token'])
206: ];
207:
208: $data['breadcrumbs'][] = [
209: 'text' => $this->language->get('heading_title'),
210: 'href' => $this->url->link('catalog/category', 'user_token=' . $this->session->data['user_token'] . $url)
211: ];
212:
213: $data['save'] = $this->url->link('catalog/category.save', 'user_token=' . $this->session->data['user_token']);
214: $data['back'] = $this->url->link('catalog/category', 'user_token=' . $this->session->data['user_token'] . $url);
215:
216: if (isset($this->request->get['category_id'])) {
217: $this->load->model('catalog/category');
218:
219: $category_info = $this->model_catalog_category->getCategory($this->request->get['category_id']);
220: }
221:
222: if (isset($this->request->get['category_id'])) {
223: $data['category_id'] = (int)$this->request->get['category_id'];
224: } else {
225: $data['category_id'] = 0;
226: }
227:
228: $this->load->model('localisation/language');
229:
230: $data['languages'] = $this->model_localisation_language->getLanguages();
231:
232: if (isset($this->request->get['category_id'])) {
233: $data['category_description'] = $this->model_catalog_category->getDescriptions($this->request->get['category_id']);
234: } else {
235: $data['category_description'] = [];
236: }
237:
238: if (!empty($category_info)) {
239: $data['path'] = $category_info['path'];
240: } else {
241: $data['path'] = '';
242: }
243:
244: if (!empty($category_info)) {
245: $data['parent_id'] = $category_info['parent_id'];
246: } else {
247: $data['parent_id'] = 0;
248: }
249:
250: $this->load->model('catalog/filter');
251:
252: if (isset($this->request->get['category_id'])) {
253: $filters = $this->model_catalog_category->getFilters($this->request->get['category_id']);
254: } else {
255: $filters = [];
256: }
257:
258: $data['category_filters'] = [];
259:
260: foreach ($filters as $filter_id) {
261: $filter_info = $this->model_catalog_filter->getFilter($filter_id);
262:
263: if ($filter_info) {
264: $data['category_filters'][] = [
265: 'filter_id' => $filter_info['filter_id'],
266: 'name' => $filter_info['group'] . ' &gt; ' . $filter_info['name']
267: ];
268: }
269: }
270:
271: $data['stores'] = [];
272:
273: $data['stores'][] = [
274: 'store_id' => 0,
275: 'name' => $this->language->get('text_default')
276: ];
277:
278: $this->load->model('setting/store');
279:
280: $stores = $this->model_setting_store->getStores();
281:
282: foreach ($stores as $store) {
283: $data['stores'][] = [
284: 'store_id' => $store['store_id'],
285: 'name' => $store['name']
286: ];
287: }
288:
289: if (isset($this->request->get['category_id'])) {
290: $data['category_store'] = $this->model_catalog_category->getStores($this->request->get['category_id']);
291: } else {
292: $data['category_store'] = [0];
293: }
294:
295: if (!empty($category_info)) {
296: $data['image'] = $category_info['image'];
297: } else {
298: $data['image'] = '';
299: }
300:
301: $this->load->model('tool/image');
302:
303: $data['placeholder'] = $this->model_tool_image->resize('no_image.png', $this->config->get('config_image_default_width'), $this->config->get('config_image_default_height'));
304:
305: if ($data['image'] && is_file(DIR_IMAGE . html_entity_decode($data['image'], ENT_QUOTES, 'UTF-8'))) {
306: $data['thumb'] = $this->model_tool_image->resize($data['image'], $this->config->get('config_image_default_width'), $this->config->get('config_image_default_height'));
307: } else {
308: $data['thumb'] = $data['placeholder'];
309: }
310:
311: if (!empty($category_info)) {
312: $data['column'] = $category_info['column'];
313: } else {
314: $data['column'] = 1;
315: }
316:
317: if (!empty($category_info)) {
318: $data['sort_order'] = $category_info['sort_order'];
319: } else {
320: $data['sort_order'] = 0;
321: }
322:
323: if (!empty($category_info)) {
324: $data['status'] = $category_info['status'];
325: } else {
326: $data['status'] = true;
327: }
328:
329: $data['category_seo_url'] = [];
330:
331: if (isset($this->request->get['category_id'])) {
332: $this->load->model('design/seo_url');
333:
334: $results = $this->model_design_seo_url->getSeoUrlsByKeyValue('path', $this->model_catalog_category->getPath($this->request->get['category_id']));
335:
336: foreach ($results as $store_id => $languages) {
337: foreach ($languages as $language_id => $keyword) {
338: $pos = strrpos($keyword, '/');
339:
340: if ($pos !== false) {
341: $keyword = substr($keyword, $pos + 1);
342: }
343:
344: $data['category_seo_url'][$store_id][$language_id] = $keyword;
345: }
346: }
347: }
348:
349: $this->load->model('design/layout');
350:
351: $data['layouts'] = $this->model_design_layout->getLayouts();
352:
353: if (isset($this->request->get['category_id'])) {
354: $data['category_layout'] = $this->model_catalog_category->getLayouts($this->request->get['category_id']);
355: } else {
356: $data['category_layout'] = [];
357: }
358:
359: $data['user_token'] = $this->session->data['user_token'];
360:
361: $data['header'] = $this->load->controller('common/header');
362: $data['column_left'] = $this->load->controller('common/column_left');
363: $data['footer'] = $this->load->controller('common/footer');
364:
365: $this->response->setOutput($this->load->view('catalog/category_form', $data));
366: }
367:
368: /**
369: * Save
370: *
371: * @return void
372: */
373: public function save(): void {
374: $this->load->language('catalog/category');
375:
376: $json = [];
377:
378: if (!$this->user->hasPermission('modify', 'catalog/category')) {
379: $json['error']['warning'] = $this->language->get('error_permission');
380: }
381:
382: foreach ($this->request->post['category_description'] as $language_id => $value) {
383: if (!oc_validate_length($value['name'], 1, 255)) {
384: $json['error']['name_' . $language_id] = $this->language->get('error_name');
385: }
386:
387: if (!oc_validate_length($value['meta_title'], 1, 255)) {
388: $json['error']['meta_title_' . $language_id] = $this->language->get('error_meta_title');
389: }
390: }
391:
392: $this->load->model('catalog/category');
393:
394: if (isset($this->request->post['category_id']) && $this->request->post['parent_id']) {
395: $results = $this->model_catalog_category->getPaths($this->request->post['parent_id']);
396:
397: foreach ($results as $result) {
398: if ($result['path_id'] == $this->request->post['category_id']) {
399: $json['error']['parent'] = $this->language->get('error_parent');
400: break;
401: }
402: }
403: }
404:
405: if ($this->request->post['category_seo_url']) {
406: $this->load->model('design/seo_url');
407:
408: foreach ($this->request->post['category_seo_url'] as $store_id => $language) {
409: foreach ($language as $language_id => $keyword) {
410: if (!oc_validate_length($keyword, 1, 64)) {
411: $json['error']['keyword_' . $store_id . '_' . $language_id] = $this->language->get('error_keyword');
412: }
413:
414: if (!oc_validate_seo_url($keyword)) {
415: $json['error']['keyword_' . $store_id . '_' . $language_id] = $this->language->get('error_keyword_character');
416: }
417:
418: $seo_url_info = $this->model_design_seo_url->getSeoUrlByKeyword($keyword, $store_id);
419:
420: if ($seo_url_info && (!isset($this->request->post['category_id']) || $seo_url_info['key'] != 'path' || $seo_url_info['value'] != $this->model_catalog_category->getPath($this->request->post['category_id']))) {
421: $json['error']['keyword_' . $store_id . '_' . $language_id] = $this->language->get('error_keyword_exists');
422: }
423: }
424: }
425: }
426:
427: if (isset($json['error']) && !isset($json['error']['warning'])) {
428: $json['error']['warning'] = $this->language->get('error_warning');
429: }
430:
431: if (!$json) {
432: if (!$this->request->post['category_id']) {
433: $json['category_id'] = $this->model_catalog_category->addCategory($this->request->post);
434: } else {
435: $this->model_catalog_category->editCategory($this->request->post['category_id'], $this->request->post);
436: }
437:
438: $json['success'] = $this->language->get('text_success');
439: }
440:
441: $this->response->addHeader('Content-Type: application/json');
442: $this->response->setOutput(json_encode($json));
443: }
444:
445: /**
446: * Repair
447: *
448: * @return void
449: */
450: public function repair(): void {
451: $this->load->language('catalog/category');
452:
453: $json = [];
454:
455: if (!$this->user->hasPermission('modify', 'catalog/category')) {
456: $json['error'] = $this->language->get('error_permission');
457: }
458:
459: if (!$json) {
460: $this->load->model('catalog/category');
461:
462: $this->model_catalog_category->repairCategories();
463:
464: $json['success'] = $this->language->get('text_success');
465: }
466:
467: $this->response->addHeader('Content-Type: application/json');
468: $this->response->setOutput(json_encode($json));
469: }
470:
471: /**
472: * Delete
473: *
474: * @return void
475: */
476: public function delete(): void {
477: $this->load->language('catalog/category');
478:
479: $json = [];
480:
481: if (isset($this->request->post['selected'])) {
482: $selected = $this->request->post['selected'];
483: } else {
484: $selected = [];
485: }
486:
487: if (!$this->user->hasPermission('modify', 'catalog/category')) {
488: $json['error'] = $this->language->get('error_permission');
489: }
490:
491: if (!$json) {
492: $this->load->model('catalog/category');
493:
494: foreach ($selected as $category_id) {
495: $this->model_catalog_category->deleteCategory($category_id);
496: }
497:
498: $json['success'] = $this->language->get('text_success');
499: }
500:
501: $this->response->addHeader('Content-Type: application/json');
502: $this->response->setOutput(json_encode($json));
503: }
504:
505: /**
506: * Autocomplete
507: *
508: * @return void
509: */
510: public function autocomplete(): void {
511: $json = [];
512:
513: if (isset($this->request->get['filter_name'])) {
514: $this->load->model('catalog/category');
515:
516: $filter_data = [
517: 'filter_name' => '%' . $this->request->get['filter_name'] . '%',
518: 'sort' => 'name',
519: 'order' => 'ASC',
520: 'start' => 0,
521: 'limit' => 5
522: ];
523:
524: $results = $this->model_catalog_category->getCategories($filter_data);
525:
526: foreach ($results as $result) {
527: $json[] = [
528: 'category_id' => $result['category_id'],
529: 'name' => $result['name']
530: ];
531: }
532: }
533:
534: $sort_order = [];
535:
536: foreach ($json as $key => $value) {
537: $sort_order[$key] = $value['name'];
538: }
539:
540: array_multisort($sort_order, SORT_ASC, $json);
541:
542: $this->response->addHeader('Content-Type: application/json');
543: $this->response->setOutput(json_encode($json));
544: }
545: }
546: