1: <?php
2: namespace Opencart\Admin\Controller\Design;
3: /**
4: * Class SEO URL
5: *
6: * @package Opencart\Admin\Controller\Design
7: */
8: class SeoUrl extends \Opencart\System\Engine\Controller {
9: /**
10: * Index
11: *
12: * @return void
13: */
14: public function index(): void {
15: $this->load->language('design/seo_url');
16:
17: $this->document->setTitle($this->language->get('heading_title'));
18:
19: if (isset($this->request->get['filter_keyword'])) {
20: $filter_keyword = (string)$this->request->get['filter_keyword'];
21: } else {
22: $filter_keyword = '';
23: }
24:
25: if (isset($this->request->get['filter_key'])) {
26: $filter_key = (string)$this->request->get['filter_key'];
27: } else {
28: $filter_key = '';
29: }
30:
31: if (isset($this->request->get['filter_value'])) {
32: $filter_value = (string)$this->request->get['filter_value'];
33: } else {
34: $filter_value = '';
35: }
36:
37: if (isset($this->request->get['filter_store_id'])) {
38: $filter_store_id = (int)$this->request->get['filter_store_id'];
39: } else {
40: $filter_store_id = '';
41: }
42:
43: if (isset($this->request->get['filter_language_id'])) {
44: $filter_language_id = (int)$this->request->get['filter_language_id'];
45: } else {
46: $filter_language_id = 0;
47: }
48:
49: $url = '';
50:
51: if (isset($this->request->get['filter_keyword'])) {
52: $url .= '&filter_keyword=' . urlencode(html_entity_decode((string)$this->request->get['filter_keyword'], ENT_QUOTES, 'UTF-8'));
53: }
54:
55: if (isset($this->request->get['filter_key'])) {
56: $url .= '&filter_key=' . urlencode(html_entity_decode((string)$this->request->get['filter_key'], ENT_QUOTES, 'UTF-8'));
57: }
58:
59: if (isset($this->request->get['filter_value'])) {
60: $url .= '&filter_value=' . urlencode(html_entity_decode((string)$this->request->get['filter_value'], ENT_QUOTES, 'UTF-8'));
61: }
62:
63: if (isset($this->request->get['filter_store_id'])) {
64: $url .= '&filter_store_id=' . (int)$this->request->get['filter_store_id'];
65: }
66:
67: if (isset($this->request->get['filter_language_id'])) {
68: $url .= '&filter_language_id=' . (int)$this->request->get['filter_language_id'];
69: }
70:
71: if (isset($this->request->get['sort'])) {
72: $url .= '&sort=' . (string)$this->request->get['sort'];
73: }
74:
75: if (isset($this->request->get['order'])) {
76: $url .= '&order=' . (string)$this->request->get['order'];
77: }
78:
79: if (isset($this->request->get['page'])) {
80: $url .= '&page=' . (int)$this->request->get['page'];
81: }
82:
83: $data['breadcrumbs'] = [];
84:
85: $data['breadcrumbs'][] = [
86: 'text' => $this->language->get('text_home'),
87: 'href' => $this->url->link('common/dashboard', 'user_token=' . $this->session->data['user_token'])
88: ];
89:
90: $data['breadcrumbs'][] = [
91: 'text' => $this->language->get('heading_title'),
92: 'href' => $this->url->link('design/seo_url', 'user_token=' . $this->session->data['user_token'] . $url)
93: ];
94:
95: $data['add'] = $this->url->link('design/seo_url.form', 'user_token=' . $this->session->data['user_token'] . $url);
96: $data['delete'] = $this->url->link('design/seo_url.delete', 'user_token=' . $this->session->data['user_token']);
97:
98: $data['list'] = $this->getList();
99:
100: $this->load->model('setting/store');
101:
102: $data['stores'] = $this->model_setting_store->getStores();
103:
104: $this->load->model('localisation/language');
105:
106: $data['languages'] = $this->model_localisation_language->getLanguages();
107:
108: $data['filter_keyword'] = $filter_keyword;
109: $data['filter_key'] = $filter_key;
110: $data['filter_value'] = $filter_value;
111: $data['filter_store_id'] = $filter_store_id;
112: $data['filter_language_id'] = $filter_language_id;
113:
114: $data['user_token'] = $this->session->data['user_token'];
115:
116: $data['header'] = $this->load->controller('common/header');
117: $data['column_left'] = $this->load->controller('common/column_left');
118: $data['footer'] = $this->load->controller('common/footer');
119:
120: $this->response->setOutput($this->load->view('design/seo_url', $data));
121: }
122:
123: /**
124: * List
125: *
126: * @return void
127: */
128: public function list(): void {
129: $this->load->language('design/seo_url');
130:
131: $this->response->setOutput($this->getList());
132: }
133:
134: /**
135: * Get List
136: *
137: * @return string
138: */
139: protected function getList(): string {
140: if (isset($this->request->get['filter_keyword'])) {
141: $filter_keyword = (string)$this->request->get['filter_keyword'];
142: } else {
143: $filter_keyword = '';
144: }
145:
146: if (isset($this->request->get['filter_key'])) {
147: $filter_key = (string)$this->request->get['filter_key'];
148: } else {
149: $filter_key = '';
150: }
151:
152: if (isset($this->request->get['filter_value'])) {
153: $filter_value = (string)$this->request->get['filter_value'];
154: } else {
155: $filter_value = '';
156: }
157:
158: if (isset($this->request->get['filter_store_id'])) {
159: $filter_store_id = (int)$this->request->get['filter_store_id'];
160: } else {
161: $filter_store_id = '';
162: }
163:
164: if (isset($this->request->get['filter_language_id'])) {
165: $filter_language_id = (int)$this->request->get['filter_language_id'];
166: } else {
167: $filter_language_id = 0;
168: }
169:
170: if (isset($this->request->get['sort'])) {
171: $sort = (string)$this->request->get['sort'];
172: } else {
173: $sort = 'key';
174: }
175:
176: if (isset($this->request->get['order'])) {
177: $order = (string)$this->request->get['order'];
178: } else {
179: $order = 'ASC';
180: }
181:
182: if (isset($this->request->get['page'])) {
183: $page = (int)$this->request->get['page'];
184: } else {
185: $page = 1;
186: }
187:
188: $url = '';
189:
190: if (isset($this->request->get['filter_keyword'])) {
191: $url .= '&filter_keyword=' . urlencode(html_entity_decode((string)$this->request->get['filter_keyword'], ENT_QUOTES, 'UTF-8'));
192: }
193:
194: if (isset($this->request->get['filter_key'])) {
195: $url .= '&filter_key=' . urlencode(html_entity_decode((string)$this->request->get['filter_key'], ENT_QUOTES, 'UTF-8'));
196: }
197:
198: if (isset($this->request->get['filter_value'])) {
199: $url .= '&filter_value=' . urlencode(html_entity_decode((string)$this->request->get['filter_value'], ENT_QUOTES, 'UTF-8'));
200: }
201:
202: if (isset($this->request->get['filter_store_id'])) {
203: $url .= '&filter_store_id=' . (int)$this->request->get['filter_store_id'];
204: }
205:
206: if (isset($this->request->get['filter_language_id'])) {
207: $url .= '&filter_language_id=' . (int)$this->request->get['filter_language_id'];
208: }
209:
210: if (isset($this->request->get['sort'])) {
211: $url .= '&sort=' . (string)$this->request->get['sort'];
212: }
213:
214: if (isset($this->request->get['order'])) {
215: $url .= '&order=' . (string)$this->request->get['order'];
216: }
217:
218: if (isset($this->request->get['page'])) {
219: $url .= '&page=' . (int)$this->request->get['page'];
220: }
221:
222: $data['action'] = $this->url->link('design/seo_url.list', 'user_token=' . $this->session->data['user_token'] . $url);
223:
224: $data['seo_urls'] = [];
225:
226: $filter_data = [
227: 'filter_keyword' => $filter_keyword,
228: 'filter_key' => $filter_key,
229: 'filter_value' => $filter_value,
230: 'filter_store_id' => $filter_store_id,
231: 'filter_language_id' => $filter_language_id,
232: 'sort' => $sort,
233: 'order' => $order,
234: 'start' => ($page - 1) * $this->config->get('config_pagination_admin'),
235: 'limit' => $this->config->get('config_pagination_admin')
236: ];
237:
238: $this->load->model('design/seo_url');
239: $this->load->model('localisation/language');
240:
241: $results = $this->model_design_seo_url->getSeoUrls($filter_data);
242:
243: foreach ($results as $result) {
244: $language_info = $this->model_localisation_language->getLanguage($result['language_id']);
245:
246: if ($language_info) {
247: $code = $language_info['code'];
248: $image = $language_info['image'];
249: } else {
250: $code = '';
251: $image = '';
252: }
253:
254: $data['seo_urls'][] = [
255: 'seo_url_id' => $result['seo_url_id'],
256: 'keyword' => $result['keyword'],
257: 'image' => $image,
258: 'language' => $code,
259: 'key' => $result['key'],
260: 'value' => $result['value'],
261: 'sort_order' => $result['sort_order'],
262: 'store' => $result['store_id'] ? $result['store'] : $this->language->get('text_default'),
263: 'edit' => $this->url->link('design/seo_url.form', 'user_token=' . $this->session->data['user_token'] . '&seo_url_id=' . $result['seo_url_id'] . $url)
264: ];
265: }
266:
267: $url = '';
268:
269: if (isset($this->request->get['filter_keyword'])) {
270: $url .= '&filter_keyword=' . urlencode(html_entity_decode((string)$this->request->get['filter_keyword'], ENT_QUOTES, 'UTF-8'));
271: }
272:
273: if (isset($this->request->get['filter_key'])) {
274: $url .= '&filter_key=' . urlencode(html_entity_decode((string)$this->request->get['filter_key'], ENT_QUOTES, 'UTF-8'));
275: }
276:
277: if (isset($this->request->get['filter_value'])) {
278: $url .= '&filter_value=' . urlencode(html_entity_decode((string)$this->request->get['filter_value'], ENT_QUOTES, 'UTF-8'));
279: }
280:
281: if (isset($this->request->get['filter_store_id'])) {
282: $url .= '&filter_store_id=' . (int)$this->request->get['filter_store_id'];
283: }
284:
285: if (isset($this->request->get['filter_language_id'])) {
286: $url .= '&filter_language_id=' . (int)$this->request->get['filter_language_id'];
287: }
288:
289: if ($order == 'ASC') {
290: $url .= '&order=DESC';
291: } else {
292: $url .= '&order=ASC';
293: }
294:
295: $data['sort_keyword'] = $this->url->link('design/seo_url.list', 'user_token=' . $this->session->data['user_token'] . '&sort=keyword' . $url);
296: $data['sort_key'] = $this->url->link('design/seo_url.list', 'user_token=' . $this->session->data['user_token'] . '&sort=key' . $url);
297: $data['sort_value'] = $this->url->link('design/seo_url.list', 'user_token=' . $this->session->data['user_token'] . '&sort=value' . $url);
298: $data['sort_sort_order'] = $this->url->link('design/seo_url.list', 'user_token=' . $this->session->data['user_token'] . '&sort=sort_order' . $url);
299: $data['sort_store'] = $this->url->link('design/seo_url.list', 'user_token=' . $this->session->data['user_token'] . '&sort=store' . $url);
300: $data['sort_language'] = $this->url->link('design/seo_url.list', 'user_token=' . $this->session->data['user_token'] . '&sort=language' . $url);
301:
302: $url = '';
303:
304: if (isset($this->request->get['filter_keyword'])) {
305: $url .= '&filter_keyword=' . urlencode(html_entity_decode((string)$this->request->get['filter_keyword'], ENT_QUOTES, 'UTF-8'));
306: }
307:
308: if (isset($this->request->get['filter_key'])) {
309: $url .= '&filter_key=' . urlencode(html_entity_decode((string)$this->request->get['filter_key'], ENT_QUOTES, 'UTF-8'));
310: }
311:
312: if (isset($this->request->get['filter_value'])) {
313: $url .= '&filter_value=' . urlencode(html_entity_decode((string)$this->request->get['filter_value'], ENT_QUOTES, 'UTF-8'));
314: }
315:
316: if (isset($this->request->get['filter_store_id'])) {
317: $url .= '&filter_store_id=' . (int)$this->request->get['filter_store_id'];
318: }
319:
320: if (isset($this->request->get['filter_language_id'])) {
321: $url .= '&filter_language_id=' . (int)$this->request->get['filter_language_id'];
322: }
323:
324: if (isset($this->request->get['sort'])) {
325: $url .= '&sort=' . (string)$this->request->get['sort'];
326: }
327:
328: if (isset($this->request->get['order'])) {
329: $url .= '&order=' . (string)$this->request->get['order'];
330: }
331:
332: $seo_url_total = $this->model_design_seo_url->getTotalSeoUrls($filter_data);
333:
334: $data['pagination'] = $this->load->controller('common/pagination', [
335: 'total' => $seo_url_total,
336: 'page' => $page,
337: 'limit' => $this->config->get('config_pagination_admin'),
338: 'url' => $this->url->link('design/seo_url.list', 'user_token=' . $this->session->data['user_token'] . $url . '&page={page}')
339: ]);
340:
341: $data['results'] = sprintf($this->language->get('text_pagination'), ($seo_url_total) ? (($page - 1) * $this->config->get('config_pagination_admin')) + 1 : 0, ((($page - 1) * $this->config->get('config_pagination_admin')) > ($seo_url_total - $this->config->get('config_pagination_admin'))) ? $seo_url_total : ((($page - 1) * $this->config->get('config_pagination_admin')) + $this->config->get('config_pagination_admin')), $seo_url_total, ceil($seo_url_total / $this->config->get('config_pagination_admin')));
342:
343: $data['sort'] = $sort;
344: $data['order'] = $order;
345:
346: return $this->load->view('design/seo_url_list', $data);
347: }
348:
349: /**
350: * Form
351: *
352: * @return void
353: */
354: public function form(): void {
355: $this->load->language('design/seo_url');
356:
357: $this->document->setTitle($this->language->get('heading_title'));
358:
359: $data['text_form'] = !isset($this->request->get['seo_url_id']) ? $this->language->get('text_add') : $this->language->get('text_edit');
360:
361: $url = '';
362:
363: if (isset($this->request->get['filter_keyword'])) {
364: $url .= '&filter_keyword=' . urlencode(html_entity_decode((string)$this->request->get['filter_keyword'], ENT_QUOTES, 'UTF-8'));
365: }
366:
367: if (isset($this->request->get['filter_key'])) {
368: $url .= '&filter_key=' . urlencode(html_entity_decode((string)$this->request->get['filter_key'], ENT_QUOTES, 'UTF-8'));
369: }
370:
371: if (isset($this->request->get['filter_value'])) {
372: $url .= '&filter_value=' . urlencode(html_entity_decode((string)$this->request->get['filter_value'], ENT_QUOTES, 'UTF-8'));
373: }
374:
375: if (isset($this->request->get['filter_store_id'])) {
376: $url .= '&filter_store_id=' . (int)$this->request->get['filter_store_id'];
377: }
378:
379: if (isset($this->request->get['filter_language_id'])) {
380: $url .= '&filter_language_id=' . (int)$this->request->get['filter_language_id'];
381: }
382:
383: if (isset($this->request->get['sort'])) {
384: $url .= '&sort=' . (string)$this->request->get['sort'];
385: }
386:
387: if (isset($this->request->get['order'])) {
388: $url .= '&order=' . (string)$this->request->get['order'];
389: }
390:
391: if (isset($this->request->get['page'])) {
392: $url .= '&page=' . (int)$this->request->get['page'];
393: }
394:
395: $data['breadcrumbs'] = [];
396:
397: $data['breadcrumbs'][] = [
398: 'text' => $this->language->get('text_home'),
399: 'href' => $this->url->link('common/dashboard', 'user_token=' . $this->session->data['user_token'])
400: ];
401:
402: $data['breadcrumbs'][] = [
403: 'text' => $this->language->get('heading_title'),
404: 'href' => $this->url->link('design/seo_url', 'user_token=' . $this->session->data['user_token'] . $url)
405: ];
406:
407: $data['save'] = $this->url->link('design/seo_url.save', 'user_token=' . $this->session->data['user_token']);
408: $data['back'] = $this->url->link('design/seo_url', 'user_token=' . $this->session->data['user_token'] . $url);
409:
410: if (isset($this->request->get['seo_url_id'])) {
411: $this->load->model('design/seo_url');
412:
413: $seo_url_info = $this->model_design_seo_url->getSeoUrl($this->request->get['seo_url_id']);
414: }
415:
416: if (isset($this->request->get['seo_url_id'])) {
417: $data['seo_url_id'] = (int)$this->request->get['seo_url_id'];
418: } else {
419: $data['seo_url_id'] = 0;
420: }
421:
422: $data['stores'] = [];
423:
424: $data['stores'][] = [
425: 'store_id' => 0,
426: 'name' => $this->language->get('text_default')
427: ];
428:
429: $this->load->model('setting/store');
430:
431: $stores = $this->model_setting_store->getStores();
432:
433: foreach ($stores as $store) {
434: $data['stores'][] = [
435: 'store_id' => $store['store_id'],
436: 'name' => $store['name']
437: ];
438: }
439:
440: if (!empty($seo_url_info)) {
441: $data['store_id'] = $seo_url_info['store_id'];
442: } else {
443: $data['store_id'] = '';
444: }
445:
446: $this->load->model('localisation/language');
447:
448: $data['languages'] = $this->model_localisation_language->getLanguages();
449:
450: if (!empty($seo_url_info)) {
451: $data['language_id'] = $seo_url_info['language_id'];
452: } else {
453: $data['language_id'] = '';
454: }
455:
456: if (!empty($seo_url_info)) {
457: $data['key'] = $seo_url_info['key'];
458: } else {
459: $data['key'] = '';
460: }
461:
462: if (!empty($seo_url_info)) {
463: $data['value'] = $seo_url_info['value'];
464: } else {
465: $data['value'] = '';
466: }
467:
468: if (!empty($seo_url_info)) {
469: $data['keyword'] = $seo_url_info['keyword'];
470: } else {
471: $data['keyword'] = '';
472: }
473:
474: if (!empty($seo_url_info)) {
475: $data['sort_order'] = $seo_url_info['sort_order'];
476: } else {
477: $data['sort_order'] = '';
478: }
479:
480: $data['header'] = $this->load->controller('common/header');
481: $data['column_left'] = $this->load->controller('common/column_left');
482: $data['footer'] = $this->load->controller('common/footer');
483:
484: $this->response->setOutput($this->load->view('design/seo_url_form', $data));
485: }
486:
487: /**
488: * Save
489: *
490: * @return void
491: */
492: public function save(): void {
493: $this->load->language('design/seo_url');
494:
495: $json = [];
496:
497: if (!$this->user->hasPermission('modify', 'design/seo_url')) {
498: $json['error']['warning'] = $this->language->get('error_permission');
499: }
500:
501: if (!oc_validate_length($this->request->post['key'], 1, 64)) {
502: $json['error']['key'] = $this->language->get('error_key');
503: }
504:
505: if (!oc_validate_length($this->request->post['value'], 1, 255)) {
506: $json['error']['value'] = $this->language->get('error_value');
507: }
508:
509: $this->load->model('design/seo_url');
510:
511: // Check if there is already a key value pair on the same store using the same language
512: $seo_url_info = $this->model_design_seo_url->getSeoUrlByKeyValue($this->request->post['key'], $this->request->post['value'], $this->request->post['store_id'], $this->request->post['language_id']);
513:
514: if ($seo_url_info && (!isset($this->request->post['seo_url_id']) || $seo_url_info['seo_url_id'] != (int)$this->request->post['seo_url_id'])) {
515: $json['error']['value'] = $this->language->get('error_value_exists');
516: }
517:
518: // Split keywords by / so we can validate each keyword
519: $keywords = explode('/', $this->request->post['keyword']);
520:
521: foreach ($keywords as $keyword) {
522: if (!oc_validate_length($keyword, 1, 64)) {
523: $json['error']['keyword'] = $this->language->get('error_keyword');
524: }
525:
526: if (!oc_validate_seo_url($keyword)) {
527: $json['error']['keyword'] = $this->language->get('error_keyword_character');
528: }
529: }
530:
531: // Check if keyword already exists and on the same store as long as the keyword matches the key / value pair
532: $seo_url_info = $this->model_design_seo_url->getSeoUrlByKeyword($this->request->post['keyword'], $this->request->post['store_id']);
533:
534: if ($seo_url_info && (($seo_url_info['key'] != $this->request->post['key']) || ($seo_url_info['value'] != $this->request->post['value']))) {
535: $json['error']['keyword'] = $this->language->get('error_keyword_exists');
536: }
537:
538: if (!$json) {
539: if (!$this->request->post['seo_url_id']) {
540: $json['seo_url_id'] = $this->model_design_seo_url->addSeoUrl($this->request->post['key'], $this->request->post['value'], $this->request->post['keyword'], $this->request->post['store_id'], $this->request->post['language_id'], $this->request->post['sort_order']);
541: } else {
542: $this->model_design_seo_url->editSeoUrl($this->request->post['seo_url_id'], $this->request->post['key'], $this->request->post['value'], $this->request->post['keyword'], $this->request->post['store_id'], $this->request->post['language_id'], $this->request->post['sort_order']);
543: }
544:
545: $json['success'] = $this->language->get('text_success');
546: }
547:
548: $this->response->addHeader('Content-Type: application/json');
549: $this->response->setOutput(json_encode($json));
550: }
551:
552: /**
553: * Delete
554: *
555: * @return void
556: */
557: public function delete(): void {
558: $this->load->language('design/seo_url');
559:
560: $json = [];
561:
562: if (isset($this->request->post['selected'])) {
563: $selected = $this->request->post['selected'];
564: } else {
565: $selected = [];
566: }
567:
568: if (!$this->user->hasPermission('modify', 'design/seo_url')) {
569: $json['error'] = $this->language->get('error_permission');
570: }
571:
572: if (!$json) {
573: $this->load->model('design/seo_url');
574:
575: foreach ($selected as $seo_url_id) {
576: $this->model_design_seo_url->deleteSeoUrl($seo_url_id);
577: }
578:
579: $json['success'] = $this->language->get('text_success');
580: }
581:
582: $this->response->addHeader('Content-Type: application/json');
583: $this->response->setOutput(json_encode($json));
584: }
585:
586: /**
587: * Refresh
588: *
589: * @return void
590: */
591: public function refresh(): void {
592: $this->load->language('design/seo_url');
593:
594: $json = [];
595:
596: if (!$this->user->hasPermission('modify', 'design/seo_url')) {
597: $json['error'] = $this->language->get('error_permission');
598: }
599:
600: if (!$json) {
601:
602: $data['seo_urls'] = [];
603:
604: $filter_data = [
605: 'filter_keyword' => $filter_keyword,
606: 'filter_key' => $filter_key,
607: 'filter_value' => $filter_value,
608: 'filter_store_id' => $filter_store_id,
609: 'filter_language_id' => $filter_language_id,
610: 'sort' => $sort,
611: 'order' => $order,
612: 'start' => ($page - 1) * $this->config->get('config_pagination_admin'),
613: 'limit' => $this->config->get('config_pagination_admin')
614: ];
615:
616: $this->load->model('design/seo_url');
617:
618: $results = $this->model_catalog_product->getProducts($filter_data);
619:
620: foreach ($results as $result) {
621:
622: $this->model_design_seo_url->deleteSeoUrl($seo_url_id);
623:
624: }
625:
626: $this->load->model('localisation/language');
627:
628: $results = $this->model_design_seo_url->getSeoUrls($filter_data);
629:
630: foreach ($results as $result) {
631:
632: $this->model_design_seo_url->deleteSeoUrl($seo_url_id);
633:
634: }
635:
636: $email_total = $this->model_design_seo_url->getTotalEmailsByProductsOrdered($this->request->post['product']);
637:
638: $start = ($page - 1) * $limit;
639: $end = $start > ($email_total - $limit) ? $email_total : ($start + $limit);
640:
641: if ($end < $total) {
642: $json['text'] = sprintf($this->language->get('text_install'), $start, $end, $total);
643:
644: $json['next'] = $this->url->link('marketplace/installer.install', 'user_token=' . $this->session->data['user_token'] . $url . '&page=' . ($page + 1), true);
645: } else {
646: $json['success'] = $this->language->get('text_success');
647:
648: $json['next'] = $this->url->link('marketplace/installer.xml', 'user_token=' . $this->session->data['user_token'] . $url, true);
649: }
650: }
651:
652: $this->response->addHeader('Content-Type: application/json');
653: $this->response->setOutput(json_encode($json));
654: }
655: }
656: