1: | <?php
2: | namespace Opencart\Admin\Controller\Marketplace;
3: | /**
4: | * Class Installer
5: | *
6: | * @package Opencart\Admin\Controller\Marketplace
7: | */
8: | class Installer extends \Opencart\System\Engine\Controller {
9: | /**
10: | * Index
11: | *
12: | * @return void
13: | */
14: | public function index(): void {
15: | $this->load->language('marketplace/installer');
16: |
17: | $this->document->setTitle($this->language->get('heading_title'));
18: |
19: | $data['breadcrumbs'] = [];
20: |
21: | $data['breadcrumbs'][] = [
22: | 'text' => $this->language->get('text_home'),
23: | 'href' => $this->url->link('common/dashboard', 'user_token=' . $this->session->data['user_token'])
24: | ];
25: |
26: | $data['breadcrumbs'][] = [
27: | 'text' => $this->language->get('heading_title'),
28: | 'href' => $this->url->link('marketplace/installer', 'user_token=' . $this->session->data['user_token'])
29: | ];
30: |
31: | // Use the configuration option to get the max file size
32: | $data['error_upload_size'] = sprintf($this->language->get('error_file_size'), ini_get('upload_max_filesize'));
33: |
34: | $data['config_file_max_size'] = ((int)preg_filter('/[^0-9]/', '', ini_get('upload_max_filesize')) * 1024 * 1024);
35: |
36: | $data['upload'] = $this->url->link('tool/installer.upload', 'user_token=' . $this->session->data['user_token']);
37: |
38: | $data['list'] = $this->getList();
39: |
40: | if (isset($this->request->get['filter_extension_download_id'])) {
41: | $data['filter_extension_download_id'] = (int)$this->request->get['filter_extension_download_id'];
42: | } else {
43: | $data['filter_extension_download_id'] = '';
44: | }
45: |
46: | $data['user_token'] = $this->session->data['user_token'];
47: |
48: | $data['header'] = $this->load->controller('common/header');
49: | $data['column_left'] = $this->load->controller('common/column_left');
50: | $data['footer'] = $this->load->controller('common/footer');
51: |
52: | $this->response->setOutput($this->load->view('marketplace/installer', $data));
53: | }
54: |
55: | /**
56: | * List
57: | *
58: | * @return void
59: | */
60: | public function list(): void {
61: | $this->load->language('marketplace/installer');
62: |
63: | $this->response->setOutput($this->getList());
64: | }
65: |
66: | /**
67: | * Get List
68: | *
69: | * @return string
70: | */
71: | public function getList(): string {
72: | $this->load->language('marketplace/installer');
73: |
74: | if (isset($this->request->get['filter_extension_download_id'])) {
75: | $filter_extension_download_id = (int)$this->request->get['filter_extension_download_id'];
76: | } else {
77: | $filter_extension_download_id = '';
78: | }
79: |
80: | if (isset($this->request->get['sort'])) {
81: | $sort = (string)$this->request->get['sort'];
82: | } else {
83: | $sort = 'name';
84: | }
85: |
86: | if (isset($this->request->get['order'])) {
87: | $order = (string)$this->request->get['order'];
88: | } else {
89: | $order = 'ASC';
90: | }
91: |
92: | if (isset($this->request->get['page'])) {
93: | $page = (int)$this->request->get['page'];
94: | } else {
95: | $page = 1;
96: | }
97: |
98: | $this->load->model('setting/extension');
99: |
100: | // Look for any new extensions
101: | $files = glob(DIR_STORAGE . 'marketplace/*.ocmod.zip');
102: |
103: | foreach ($files as $file) {
104: | $code = basename($file, '.ocmod.zip');
105: |
106: | $install_info = $this->model_setting_extension->getInstallByCode($code);
107: |
108: | if (!$install_info) {
109: | // Unzip the files
110: | $zip = new \ZipArchive();
111: |
112: | if ($zip->open($file, \ZipArchive::RDONLY)) {
113: | $install_info = json_decode($zip->getFromName('install.json'), true);
114: |
115: | if ($install_info) {
116: | $keys = [
117: | 'extension_id',
118: | 'extension_download_id',
119: | 'name',
120: | 'description',
121: | 'code',
122: | 'version',
123: | 'author',
124: | 'link'
125: | ];
126: |
127: | foreach ($keys as $key) {
128: | if (!isset($install_info[$key])) {
129: | $install_info[$key] = '';
130: | }
131: | }
132: |
133: | $extension_data = [
134: | 'extension_id' => $install_info['extension_id'],
135: | 'extension_download_id' => $install_info['extension_download_id'],
136: | 'name' => strip_tags($install_info['name']),
137: | 'description' => nl2br(strip_tags($install_info['description'])),
138: | 'code' => $code,
139: | 'version' => $install_info['version'],
140: | 'author' => $install_info['author'],
141: | 'link' => $install_info['link']
142: | ];
143: |
144: | $this->model_setting_extension->addInstall($extension_data);
145: | }
146: |
147: | $zip->close();
148: | }
149: | }
150: | }
151: |
152: | $data['extensions'] = [];
153: |
154: | $filter_data = [
155: | 'filter_extension_download_id' => $filter_extension_download_id,
156: | 'sort' => $sort,
157: | 'order' => $order,
158: | 'start' => ($page - 1) * $this->config->get('config_pagination_admin'),
159: | 'limit' => $this->config->get('config_pagination_admin')
160: | ];
161: |
162: | $results = $this->model_setting_extension->getInstalls($filter_data);
163: |
164: | foreach ($results as $result) {
165: | if ($result['extension_id']) {
166: | $link = $this->url->link('marketplace/marketplace.info', 'user_token=' . $this->session->data['user_token'] . '&extension_id=' . $result['extension_id']);
167: | } elseif ($result['link']) {
168: | $link = $result['link'];
169: | } else {
170: | $link = '';
171: | }
172: |
173: | $data['extensions'][] = [
174: | 'extension_install_id' => $result['extension_install_id'],
175: | 'name' => $result['name'],
176: | 'description' => $result['description'],
177: | 'code' => $result['code'],
178: | 'version' => $result['version'],
179: | 'author' => $result['author'],
180: | 'status' => $result['status'],
181: | 'link' => $link,
182: | 'date_added' => date($this->language->get('date_format_short'), strtotime($result['date_added'])),
183: | 'install' => $this->url->link('marketplace/installer.install', 'user_token=' . $this->session->data['user_token'] . '&extension_install_id=' . $result['extension_install_id']),
184: | 'uninstall' => $this->url->link('marketplace/installer.uninstall', 'user_token=' . $this->session->data['user_token'] . '&extension_install_id=' . $result['extension_install_id']),
185: | 'delete' => $this->url->link('marketplace/installer.delete', 'user_token=' . $this->session->data['user_token'] . '&extension_install_id=' . $result['extension_install_id'])
186: | ];
187: | }
188: |
189: | $url = '';
190: |
191: | if (isset($this->request->get['filter_extension_id'])) {
192: | $url .= '&filter_extension_id=' . $this->request->get['filter_extension_id'];
193: | }
194: |
195: | if ($order == 'ASC') {
196: | $url .= '&order=DESC';
197: | } else {
198: | $url .= '&order=ASC';
199: | }
200: |
201: | $data['sort_name'] = $this->url->link('marketplace/installer.list', 'user_token=' . $this->session->data['user_token'] . '&sort=name' . $url);
202: | $data['sort_version'] = $this->url->link('marketplace/installer.list', 'user_token=' . $this->session->data['user_token'] . '&sort=version' . $url);
203: | $data['sort_date_added'] = $this->url->link('marketplace/installer.list', 'user_token=' . $this->session->data['user_token'] . '&sort=date_added' . $url);
204: |
205: | $extension_total = $this->model_setting_extension->getTotalInstalls($filter_data);
206: |
207: | $data['pagination'] = $this->load->controller('common/pagination', [
208: | 'total' => $extension_total,
209: | 'page' => $page,
210: | 'limit' => $this->config->get('config_pagination_admin'),
211: | 'url' => $this->url->link('marketplace/installer.list', 'user_token=' . $this->session->data['user_token'] . '&page={page}')
212: | ]);
213: |
214: | $data['results'] = sprintf($this->language->get('text_pagination'), ($extension_total) ? (($page - 1) * $this->config->get('config_pagination_admin')) + 1 : 0, ((($page - 1) * $this->config->get('config_pagination_admin')) > ($extension_total - $this->config->get('config_pagination_admin'))) ? $extension_total : ((($page - 1) * $this->config->get('config_pagination_admin')) + $this->config->get('config_pagination_admin')), $extension_total, ceil($extension_total / $this->config->get('config_pagination_admin')));
215: |
216: | $data['sort'] = $sort;
217: | $data['order'] = $order;
218: |
219: | return $this->load->view('marketplace/installer_extension', $data);
220: | }
221: |
222: | /**
223: | * Upload
224: | *
225: | * @return void
226: | */
227: | public function upload(): void {
228: | $this->load->language('marketplace/installer');
229: |
230: | $json = [];
231: |
232: | // 1. Validate the file uploaded.
233: | if (isset($this->request->files['file']['name'])) {
234: | $filename = basename($this->request->files['file']['name']);
235: | $code = basename($filename, '.ocmod.zip');
236: |
237: | // 2. Validate the filename.
238: | if (!oc_validate_length($filename, 1, 128)) {
239: | $json['error'] = $this->language->get('error_filename');
240: | }
241: |
242: | // 3. Validate is ocmod file.
243: | if (substr($filename, -10) != '.ocmod.zip') {
244: | $json['error'] = $this->language->get('error_file_type');
245: | }
246: |
247: | // 4. check if there is already a file
248: | $file = DIR_STORAGE . 'marketplace/' . $filename;
249: |
250: | if (is_file($file)) {
251: | $json['error'] = $this->language->get('error_file_exists');
252: |
253: | unlink($this->request->files['file']['tmp_name']);
254: | }
255: |
256: | if ($this->request->files['file']['error'] != UPLOAD_ERR_OK) {
257: | $json['error'] = $this->language->get('error_upload_' . $this->request->files['file']['error']);
258: | }
259: |
260: | if ($this->model_setting_extension->getInstallByCode($code)) {
261: | $json['error'] = $this->language->get('error_installed');
262: | }
263: | } else {
264: | $json['error'] = $this->language->get('error_upload');
265: | }
266: |
267: | // 5. Validate if the file can be opened and there is install.json that can be read.
268: | if (!$json) {
269: | move_uploaded_file($this->request->files['file']['tmp_name'], $file);
270: |
271: | // Unzip the files
272: | $zip = new \ZipArchive();
273: |
274: | if ($zip->open($file, \ZipArchive::RDONLY)) {
275: | $install_info = json_decode($zip->getFromName('install.json'), true);
276: |
277: | if ($install_info) {
278: | $keys = [
279: | 'extension_id',
280: | 'extension_download_id',
281: | 'name',
282: | 'description',
283: | 'code',
284: | 'version',
285: | 'author',
286: | 'link'
287: | ];
288: |
289: | foreach ($keys as $key) {
290: | if (!isset($install_info[$key])) {
291: | $install_info[$key] = '';
292: | }
293: | }
294: | } else {
295: | $json['error'] = $this->language->get('error_install');
296: | }
297: |
298: | $zip->close();
299: | } else {
300: | $json['error'] = $this->language->get('error_unzip');
301: | }
302: | }
303: |
304: | if (!$json) {
305: | $extension_data = [
306: | 'extension_id' => 0,
307: | 'extension_download_id' => 0,
308: | 'name' => $install_info['name'],
309: | 'description' => $install_info['description'],
310: | 'code' => $code,
311: | 'version' => $install_info['version'],
312: | 'author' => $install_info['author'],
313: | 'link' => $install_info['link']
314: | ];
315: |
316: | $this->load->model('setting/extension');
317: |
318: | $this->model_setting_extension->addInstall($extension_data);
319: |
320: | $json['success'] = $this->language->get('text_upload');
321: | }
322: |
323: | $this->response->addHeader('Content-Type: application/json');
324: | $this->response->setOutput(json_encode($json));
325: | }
326: |
327: | /**
328: | * Install
329: | *
330: | * @return void
331: | */
332: | public function install(): void {
333: | $this->load->language('marketplace/installer');
334: |
335: | $json = [];
336: |
337: | if (isset($this->request->get['extension_install_id'])) {
338: | $extension_install_id = (int)$this->request->get['extension_install_id'];
339: | } else {
340: | $extension_install_id = 0;
341: | }
342: |
343: | if (isset($this->request->get['page'])) {
344: | $page = (int)$this->request->get['page'];
345: | } else {
346: | $page = 1;
347: | }
348: |
349: | if (!$this->user->hasPermission('modify', 'marketplace/installer')) {
350: | $json['error'] = $this->language->get('error_permission');
351: | }
352: |
353: | $this->load->model('setting/extension');
354: |
355: | $extension_install_info = $this->model_setting_extension->getInstall($extension_install_id);
356: |
357: | if ($extension_install_info) {
358: | $file = DIR_STORAGE . 'marketplace/' . $extension_install_info['code'] . '.ocmod.zip';
359: |
360: | if (!is_file($file)) {
361: | $json['error'] = sprintf($this->language->get('error_file'), $extension_install_info['code'] . '.ocmod.zip');
362: | }
363: |
364: | if ($page == 1 && is_dir(DIR_EXTENSION . $extension_install_info['code'] . '/')) {
365: | $json['error'] = sprintf($this->language->get('error_directory_exists'), $extension_install_info['code'] . '/');
366: | }
367: |
368: | if ($page > 1 && !is_dir(DIR_EXTENSION . $extension_install_info['code'] . '/')) {
369: | $json['error'] = sprintf($this->language->get('error_directory'), $extension_install_info['code'] . '/');
370: | }
371: | } else {
372: | $json['error'] = $this->language->get('error_extension');
373: | }
374: |
375: | if (!$json) {
376: | // Unzip the files
377: | $zip = new \ZipArchive();
378: |
379: | if ($zip->open($file, \ZipArchive::RDONLY)) {
380: | $total = $zip->numFiles;
381: | $limit = 200;
382: |
383: | $start = ($page - 1) * $limit;
384: | $end = $start > ($total - $limit) ? $total : ($start + $limit);
385: |
386: | // Check if any of the files already exist.
387: | for ($i = $start; $i < $end; $i++) {
388: | $source = $zip->getNameIndex($i);
389: |
390: | $destination = str_replace('\\', '/', $source);
391: |
392: | // Only extract the contents of the upload folder
393: | $path = $extension_install_info['code'] . '/' . $destination;
394: | $base = DIR_EXTENSION;
395: | $prefix = '';
396: |
397: | // OCMOD files should not be copied across
398: | if (substr($destination, 0, 6) == 'ocmod/') {
399: | continue;
400: | }
401: |
402: | // image > image
403: | if (substr($destination, 0, 6) == 'image/') {
404: | $path = $destination;
405: | $base = substr(DIR_IMAGE, 0, -6);
406: | }
407: |
408: | // We need to store the path differently for vendor folders.
409: | if (substr($destination, 0, 15) == 'system/storage/') {
410: | $path = substr($destination, 15);
411: | $base = DIR_STORAGE;
412: | $prefix = 'system/storage/';
413: | }
414: |
415: | // Must not have a path before files and directories can be moved
416: | $path_new = '';
417: |
418: | $directories = explode('/', dirname($path));
419: |
420: | foreach ($directories as $directory) {
421: | if (!$path_new) {
422: | $path_new = $directory;
423: | } else {
424: | $path_new = $path_new . '/' . $directory;
425: | }
426: |
427: | // To fix storage location
428: | if (!is_dir($base . $path_new . '/') && mkdir($base . $path_new . '/', 0777)) {
429: | $this->model_setting_extension->addPath($extension_install_id, $prefix . $path_new);
430: | }
431: | }
432: |
433: | // If check if the path is not directory and check there is no existing file
434: | if (substr($source, -1) != '/') {
435: | if (!is_file($base . $path) && file_put_contents($base . $path, $zip->getFromIndex($i)) !== false) {
436: | $this->model_setting_extension->addPath($extension_install_id, $prefix . $path);
437: | }
438: | }
439: | }
440: |
441: | $zip->close();
442: |
443: | $this->model_setting_extension->editStatus($extension_install_id, true);
444: | } else {
445: | $json['error'] = $this->language->get('error_unzip');
446: | }
447: | }
448: |
449: | if (!$json) {
450: | $json['text'] = sprintf($this->language->get('text_install'), $start, $end, $total);
451: |
452: | $url = '';
453: |
454: | if (isset($this->request->get['extension_install_id'])) {
455: | $url .= '&extension_install_id=' . $this->request->get['extension_install_id'];
456: | }
457: |
458: | if ($end < $total) {
459: | $json['next'] = $this->url->link('marketplace/installer.install', 'user_token=' . $this->session->data['user_token'] . $url . '&page=' . ($page + 1), true);
460: | } else {
461: | $json['next'] = $this->url->link('marketplace/installer.xml', 'user_token=' . $this->session->data['user_token'] . $url, true);
462: | }
463: | }
464: |
465: | $this->response->addHeader('Content-Type: application/json');
466: | $this->response->setOutput(json_encode($json));
467: | }
468: |
469: | /**
470: | * Xml
471: | *
472: | * @return void
473: | */
474: | public function xml(): void {
475: | $this->load->language('marketplace/installer');
476: |
477: | $json = [];
478: |
479: | if (isset($this->request->get['extension_install_id'])) {
480: | $extension_install_id = $this->request->get['extension_install_id'];
481: | } else {
482: | $extension_install_id = 0;
483: | }
484: |
485: | if (!$this->user->hasPermission('modify', 'marketplace/installer')) {
486: | $json['error'] = $this->language->get('error_permission');
487: | }
488: |
489: | $this->load->model('setting/extension');
490: |
491: | $extension_install_info = $this->model_setting_extension->getInstall($extension_install_id);
492: |
493: | if ($extension_install_info) {
494: | $file = DIR_STORAGE . 'marketplace/' . $extension_install_info['code'] . '.ocmod.zip';
495: |
496: | if (!is_file($file)) {
497: | $json['error'] = sprintf($this->language->get('error_file'), $extension_install_info['code'] . '.ocmod.zip');
498: | }
499: | } else {
500: | $json['error'] = $this->language->get('error_extension');
501: | }
502: |
503: | if (!$json) {
504: | // Unzip the files
505: | $zip = new \ZipArchive();
506: |
507: | if ($zip->open($file, \ZipArchive::RDONLY)) {
508: | $this->load->model('setting/modification');
509: |
510: | // If xml file just put it straight into the DB
511: | // Check if any of the files already exist.
512: | for ($i = 0; $i < $zip->numFiles; $i++) {
513: | $source = $zip->getNameIndex($i);
514: |
515: | if (substr($source, 0, 6) == 'ocmod/' && substr($source, -10) == '.ocmod.xml') {
516: | $code = basename($source, '.ocmod.xml');
517: |
518: | // Check to see if the modification is already installed or not.
519: | $modification_info = $this->model_setting_modification->getModificationByCode($code);
520: |
521: | if (!$modification_info) {
522: | $xml = $zip->getFromName($source);
523: |
524: | if ($xml) {
525: | try {
526: | $dom = new \DOMDocument('1.0', 'UTF-8');
527: | $dom->loadXml($xml);
528: |
529: | $name = $dom->getElementsByTagName('name')->item(0);
530: |
531: | if ($name) {
532: | $name = $name->nodeValue;
533: | } else {
534: | $name = '';
535: | }
536: |
537: | $description = $dom->getElementsByTagName('description')->item(0);
538: |
539: | if ($description) {
540: | $description = $description->nodeValue;
541: | } else {
542: | $description = '';
543: | }
544: |
545: | $author = $dom->getElementsByTagName('author')->item(0);
546: |
547: | if ($author) {
548: | $author = $author->nodeValue;
549: | } else {
550: | $author = '';
551: | }
552: |
553: | $version = $dom->getElementsByTagName('version')->item(0);
554: |
555: | if ($version) {
556: | $version = $version->nodeValue;
557: | } else {
558: | $version = '';
559: | }
560: |
561: | $link = $dom->getElementsByTagName('link')->item(0);
562: |
563: | if ($link) {
564: | $link = $link->nodeValue;
565: | } else {
566: | $link = '';
567: | }
568: |
569: | $modification_data = [
570: | 'extension_install_id' => $extension_install_id,
571: | 'name' => strip_tags($name),
572: | 'description' => nl2br(strip_tags($description)),
573: | 'code' => $code,
574: | 'author' => $author,
575: | 'version' => $version,
576: | 'link' => $link,
577: | 'xml' => $xml,
578: | 'status' => 0
579: | ];
580: |
581: | $this->model_setting_modification->addModification($modification_data);
582: | } catch (\Exception $exception) {
583: | $json['error'] = sprintf($this->language->get('error_exception'), $exception->getCode(), $exception->getMessage(), $exception->getFile(), $exception->getLine());
584: | }
585: | }
586: | }
587: | }
588: | }
589: | } else {
590: | $json['error'] = $this->language->get('error_unzip');
591: | }
592: | }
593: |
594: | if (!$json) {
595: | $json['text'] = $this->language->get('text_vendor');
596: |
597: | $json['next'] = str_replace('&amp;', '&', $this->url->link('marketplace/installer.vendor', 'user_token=' . $this->session->data['user_token'], true));
598: | }
599: |
600: | $this->response->addHeader('Content-Type: application/json');
601: | $this->response->setOutput(json_encode($json));
602: | }
603: |
604: | /**
605: | * Vendor
606: | *
607: | * Generate new autoloader file
608: | *
609: | * @return void
610: | */
611: | public function vendor(): void {
612: | $this->load->language('marketplace/installer');
613: |
614: | $json = [];
615: |
616: | if (!$this->user->hasPermission('modify', 'marketplace/installer')) {
617: | $json['error'] = $this->language->get('error_permission');
618: | }
619: |
620: | if (!$json) {
621: | // Generate php autoload file
622: | $code = '<?php' . "\n";
623: |
624: | $files = glob(DIR_STORAGE . 'vendor/*/*/composer.json');
625: |
626: | foreach ($files as $file) {
627: | $output = json_decode(file_get_contents($file), true);
628: |
629: | $code .= '// ' . $output['name'] . "\n";
630: |
631: | if (isset($output['autoload'])) {
632: | $directory = substr(dirname($file), strlen(DIR_STORAGE . 'vendor/'));
633: |
634: | // Autoload psr-4 files
635: | if (isset($output['autoload']['psr-4'])) {
636: | $autoload = $output['autoload']['psr-4'];
637: |
638: | foreach ($autoload as $namespace => $path) {
639: | if (!is_array($path)) {
640: | $code .= '$autoloader->register(\'' . rtrim($namespace, '\\') . '\', DIR_STORAGE . \'vendor/' . $directory . '/' . rtrim($path, '/') . '/' . '\', true);' . "\n";
641: | } else {
642: | foreach ($path as $value) {
643: | $code .= '$autoloader->register(\'' . rtrim($namespace, '\\') . '\', DIR_STORAGE . \'vendor/' . $directory . '/' . rtrim($value, '/') . '/' . '\', true);' . "\n";
644: | }
645: | }
646: | }
647: | }
648: |
649: | // Autoload psr-0 files
650: | if (isset($output['autoload']['psr-0'])) {
651: | $autoload = $output['autoload']['psr-0'];
652: |
653: | foreach ($autoload as $namespace => $path) {
654: | if (!is_array($path)) {
655: | $code .= '$autoloader->register(\'' . rtrim($namespace, '\\') . '\', DIR_STORAGE . \'vendor/' . $directory . '/' . rtrim($path, '/') . '/' . '\', true);' . "\n";
656: | } else {
657: | foreach ($path as $value) {
658: | $code .= '$autoloader->register(\'' . rtrim($namespace, '\\') . '\', DIR_STORAGE . \'vendor/' . $directory . '/' . rtrim($value, '/') . '/' . '\', true);' . "\n";
659: | }
660: | }
661: | }
662: | }
663: |
664: | // Autoload classmap
665: | if (isset($output['autoload']['classmap'])) {
666: | $autoload = [];
667: |
668: | $classmaps = $output['autoload']['classmap'];
669: |
670: | foreach ($classmaps as $classmap) {
671: | $directories = [dirname($file) . '/' . $classmap];
672: |
673: | while (count($directories) != 0) {
674: | $next = array_shift($directories);
675: |
676: | if (is_dir($next)) {
677: | foreach (glob(trim($next, '/') . '/{*,.[!.]*,..?*}', GLOB_BRACE) as $file) {
678: | if (is_dir($file)) {
679: | $directories[] = $file . '/';
680: | }
681: |
682: | if (is_file($file)) {
683: | $namespace = substr(dirname($file), strlen(DIR_STORAGE . 'vendor/' . $directory . $classmap) + 1);
684: |
685: | if ($namespace) {
686: | $autoload[$namespace] = substr(dirname($file), strlen(DIR_STORAGE . 'vendor/'));
687: | }
688: | }
689: | }
690: | }
691: | }
692: | }
693: |
694: | foreach ($autoload as $namespace => $path) {
695: | $code .= '$autoloader->register(\'' . rtrim($namespace, '\\') . '\', DIR_STORAGE . \'vendor/' . rtrim($path, '/') . '/' . '\', true);' . "\n";
696: | }
697: | }
698: |
699: | // Autoload files
700: | if (isset($output['autoload']['files'])) {
701: | $files = $output['autoload']['files'];
702: |
703: | foreach ($files as $file) {
704: | $code .= 'if (is_file(DIR_STORAGE . \'vendor/' . $directory . '/' . $file . '\')) {' . "\n";
705: | $code .= ' require_once(DIR_STORAGE . \'vendor/' . $directory . '/' . $file . '\');' . "\n";
706: | $code .= '}' . "\n";
707: | }
708: | }
709: | }
710: |
711: | $code .= "\n";
712: | }
713: |
714: | file_put_contents(DIR_SYSTEM . 'vendor.php', trim($code));
715: |
716: | $json['success'] = $this->language->get('text_success');
717: | }
718: |
719: | $this->response->addHeader('Content-Type: application/json');
720: | $this->response->setOutput(json_encode($json));
721: | }
722: |
723: | /**
724: | * Uninstall
725: | *
726: | * @return void
727: | */
728: | public function uninstall(): void {
729: | $this->load->language('marketplace/installer');
730: |
731: | $json = [];
732: |
733: | if (isset($this->request->get['extension_install_id'])) {
734: | $extension_install_id = (int)$this->request->get['extension_install_id'];
735: | } else {
736: | $extension_install_id = 0;
737: | }
738: |
739: | if (!$this->user->hasPermission('modify', 'marketplace/installer')) {
740: | $json['error'] = $this->language->get('error_permission');
741: | }
742: |
743: | $this->load->model('setting/extension');
744: |
745: | $extension_install_info = $this->model_setting_extension->getInstall($extension_install_id);
746: |
747: | if ($extension_install_info) {
748: | if ($extension_install_info['code'] == 'opencart') {
749: | $json['error'] = $this->language->get('error_default');
750: | }
751: |
752: | // Validate if extension being uninstalled
753: | $extension_total = $this->model_setting_extension->getTotalExtensionsByExtension($extension_install_info['code']);
754: |
755: | if ($extension_total) {
756: | $json['error'] = sprintf($this->language->get('error_uninstall'), $extension_total);
757: | }
758: | } else {
759: | $json['error'] = $this->language->get('error_extension');
760: | }
761: |
762: | if (!$json) {
763: | $files = [];
764: |
765: | // Make path into an array
766: | $directory = [DIR_EXTENSION . $extension_install_info['code'] . '/'];
767: |
768: | // While the path array is still populated keep looping through
769: | while (count($directory) != 0) {
770: | $next = array_shift($directory);
771: |
772: | if (is_dir($next)) {
773: | foreach (glob(rtrim($next, '/') . '/{*,.[!.]*,..?*}', GLOB_BRACE) as $file) {
774: | // If directory add to path array
775: | $directory[] = $file;
776: | }
777: | }
778: |
779: | // Add the file to the files to be deleted array
780: | $files[] = $next;
781: | }
782: |
783: | // Reverse sort the file array
784: | rsort($files);
785: |
786: | foreach ($files as $file) {
787: | // If file just delete
788: | if (is_file($file)) {
789: | unlink($file);
790: | }
791: |
792: | // If directory use the remove directory function
793: | if (is_dir($file)) {
794: | rmdir($file);
795: | }
796: | }
797: |
798: | // Remove extension directory and files
799: | $results = $this->model_setting_extension->getPathsByExtensionInstallId($extension_install_id);
800: |
801: | rsort($results);
802: |
803: | foreach ($results as $result) {
804: | $path = '';
805: |
806: | // Remove images
807: | if (substr($result['path'], 0, 6) == 'image/') {
808: | $path = DIR_IMAGE . substr($result['path'], 6);
809: | }
810: |
811: | // Remove vendor files or any connected extensions that was also installed.
812: | if (substr($result['path'], 0, 15) == 'system/storage/') {
813: | $path = DIR_STORAGE . substr($result['path'], 15);
814: | }
815: |
816: | // Check if the location exists or not
817: | $path_total = $this->model_setting_extension->getTotalPaths($result['path']);
818: |
819: | if ($path_total < 2) {
820: | if (is_file($path)) {
821: | unlink($path);
822: | }
823: |
824: | if (is_dir($path)) {
825: | rmdir($path);
826: | }
827: | }
828: |
829: | $this->model_setting_extension->deletePath($result['extension_path_id']);
830: | }
831: |
832: | // Remove extension directory
833: | $this->model_setting_extension->editStatus($extension_install_id, false);
834: |
835: | // Remove any OCMOD modifications
836: | $this->load->model('setting/modification');
837: |
838: | $this->model_setting_modification->deleteModificationsByExtensionInstallId($extension_install_id);
839: |
840: | $json['text'] = $this->language->get('text_vendor');
841: |
842: | $url = '';
843: |
844: | if (isset($this->request->get['extension_install_id'])) {
845: | $url .= '&extension_install_id=' . $this->request->get['extension_install_id'];
846: | }
847: |
848: | $json['next'] = $this->url->link('marketplace/installer.vendor', 'user_token=' . $this->session->data['user_token'] . $url, true);
849: | }
850: |
851: | $this->response->addHeader('Content-Type: application/json');
852: | $this->response->setOutput(json_encode($json));
853: | }
854: |
855: | /**
856: | * Delete
857: | *
858: | * @return void
859: | */
860: | public function delete(): void {
861: | $this->load->language('marketplace/installer');
862: |
863: | $json = [];
864: |
865: | if (isset($this->request->get['extension_install_id'])) {
866: | $extension_install_id = (int)$this->request->get['extension_install_id'];
867: | } else {
868: | $extension_install_id = 0;
869: | }
870: |
871: | if (!$this->user->hasPermission('modify', 'marketplace/installer')) {
872: | $json['error'] = $this->language->get('error_permission');
873: | }
874: |
875: | $this->load->model('setting/extension');
876: |
877: | $extension_install_info = $this->model_setting_extension->getInstall($extension_install_id);
878: |
879: | if ($extension_install_info && $extension_install_info['code'] == 'opencart') {
880: | $json['error'] = $this->language->get('error_default');
881: | }
882: |
883: | if (!$extension_install_info) {
884: | $json['error'] = $this->language->get('error_extension');
885: | }
886: |
887: | if (!$json) {
888: | $file = DIR_STORAGE . 'marketplace/' . $extension_install_info['code'] . '.ocmod.zip';
889: |
890: | // Remove file
891: | if (is_file($file)) {
892: | unlink($file);
893: | }
894: |
895: | $this->model_setting_extension->deleteInstall($extension_install_id);
896: |
897: | $json['success'] = $this->language->get('text_success');
898: | }
899: |
900: | $this->response->addHeader('Content-Type: application/json');
901: | $this->response->setOutput(json_encode($json));
902: | }
903: | }
904: |

OpenCart API API documentation generated by ApiGen dev-master