1: <?php
2: /*
3: Upgrade Process
4:
5: 1. Check for latest version
6:
7: 2. Download a copy of the latest version
8:
9: 3. Add and replace the files with the ones from latest version
10:
11: 4. Redirect to upgrade page
12: */
13: namespace Opencart\Admin\Controller\Tool;
14: /**
15: * Class Upgrade
16: *
17: * @package Opencart\Admin\Controller\Tool
18: */
19: class Upgrade extends \Opencart\System\Engine\Controller {
20: /**
21: * Index
22: *
23: * @return void
24: */
25: public function index(): void {
26: $this->load->language('tool/upgrade');
27:
28: $this->document->setTitle($this->language->get('heading_title'));
29:
30: $data['breadcrumbs'] = [];
31:
32: $data['breadcrumbs'][] = [
33: 'text' => $this->language->get('text_home'),
34: 'href' => $this->url->link('common/dashboard', 'user_token=' . $this->session->data['user_token'])
35: ];
36:
37: $data['breadcrumbs'][] = [
38: 'text' => $this->language->get('heading_title'),
39: 'href' => $this->url->link('tool/upgrade', 'user_token=' . $this->session->data['user_token'])
40: ];
41:
42: $data['current_version'] = VERSION;
43: $data['upgrade'] = false;
44:
45: $curl = curl_init(OPENCART_SERVER . 'index.php?route=api/upgrade');
46:
47: curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
48: curl_setopt($curl, CURLOPT_FORBID_REUSE, 1);
49: curl_setopt($curl, CURLOPT_FRESH_CONNECT, 1);
50: curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);
51:
52: $response = curl_exec($curl);
53:
54: curl_close($curl);
55:
56: $response_info = json_decode($response, true);
57:
58: if ($response_info) {
59: $data['latest_version'] = $response_info['version'];
60: $data['date_added'] = date($this->language->get('date_format_short'), strtotime($response_info['date_added']));
61: $data['log'] = nl2br($response_info['log']);
62:
63: if (!version_compare(VERSION, $response_info['version'], '>=')) {
64: $data['upgrade'] = true;
65: }
66: } else {
67: $data['latest_version'] = '';
68: $data['date_added'] = '';
69: $data['log'] = '';
70: }
71:
72: // For testing
73: //$data['latest_version'] = 'master';
74:
75: $data['user_token'] = $this->session->data['user_token'];
76:
77: $data['header'] = $this->load->controller('common/header');
78: $data['column_left'] = $this->load->controller('common/column_left');
79: $data['footer'] = $this->load->controller('common/footer');
80:
81: $this->response->setOutput($this->load->view('tool/upgrade', $data));
82: }
83:
84: /**
85: * Download
86: *
87: * @return void
88: */
89: public function download(): void {
90: $this->load->language('tool/upgrade');
91:
92: $json = [];
93:
94: if (isset($this->request->get['version'])) {
95: $version = $this->request->get['version'];
96: } else {
97: $version = '';
98: }
99:
100: if (!$this->user->hasPermission('modify', 'tool/upgrade')) {
101: $json['error'] = $this->language->get('error_permission');
102: }
103:
104: if (version_compare($version, VERSION, '<')) {
105: $json['error'] = $this->language->get('error_version');
106: }
107:
108: $file = DIR_DOWNLOAD . 'opencart-' . $version . '.zip';
109:
110: $handle = fopen($file, 'w');
111:
112: set_time_limit(0);
113:
114: $curl = curl_init('https://github.com/opencart/opencart/archive/' . $version . '.zip');
115:
116: curl_setopt($curl, CURLOPT_USERAGENT, 'OpenCart ' . VERSION);
117: curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);
118: curl_setopt($curl, CURLOPT_FORBID_REUSE, 1);
119: curl_setopt($curl, CURLOPT_FRESH_CONNECT, 1);
120: curl_setopt($curl, CURLOPT_TIMEOUT, 300);
121: curl_setopt($curl, CURLOPT_FILE, $handle);
122:
123: curl_exec($curl);
124:
125: fclose($handle);
126:
127: $status = curl_getinfo($curl, CURLINFO_HTTP_CODE);
128:
129: if ($status != 200) {
130: $json['error'] = $this->language->get('error_download');
131: }
132:
133: curl_close($curl);
134:
135: if (!$json) {
136: $json['text'] = $this->language->get('text_install');
137:
138: $json['next'] = $this->url->link('tool/upgrade.install', 'user_token=' . $this->session->data['user_token'] . '&version=' . $version, true);
139: }
140:
141: $this->response->addHeader('Content-Type: application/json');
142: $this->response->setOutput(json_encode($json));
143: }
144:
145: /**
146: * Install
147: *
148: * @return void
149: */
150: public function install(): void {
151: $this->load->language('tool/upgrade');
152:
153: $json = [];
154:
155: if (isset($this->request->get['version'])) {
156: $version = $this->request->get['version'];
157: } else {
158: $version = '';
159: }
160:
161: if (!$this->user->hasPermission('modify', 'tool/upgrade')) {
162: $json['error'] = $this->language->get('error_permission');
163: }
164:
165: $file = DIR_DOWNLOAD . 'opencart-' . $version . '.zip';
166:
167: if (!is_file($file)) {
168: $json['error'] = $this->language->get('error_file');
169: }
170:
171: if (!$json) {
172: // Unzip the files
173: $zip = new \ZipArchive();
174:
175: if ($zip->open($file, \ZipArchive::RDONLY)) {
176: $remove = 'opencart-' . $version . '/upload/';
177:
178: // Check if any of the files already exist.
179: for ($i = 0; $i < $zip->numFiles; $i++) {
180: $source = $zip->getNameIndex($i);
181:
182: if (substr($source, 0, strlen($remove)) == $remove) {
183: // Only extract the contents of the upload folder
184: $destination = str_replace('\\', '/', substr($source, strlen($remove)));
185:
186: if (substr($destination, 0, 8) == 'install/') {
187: // Default copy location
188: $path = '';
189:
190: // Must not have a path before files and directories can be moved
191: $directories = explode('/', dirname($destination));
192:
193: foreach ($directories as $directory) {
194: if (!$path) {
195: $path = $directory;
196: } else {
197: $path = $path . '/' . $directory;
198: }
199:
200: if (!is_dir(DIR_OPENCART . $path) && !@mkdir(DIR_OPENCART . $path, 0777)) {
201: $json['error'] = sprintf($this->language->get('error_directory'), $path);
202: }
203: }
204:
205: // Check if the path is not directory and check there is no existing file
206: if (substr($destination, -1) != '/') {
207: if (is_file(DIR_OPENCART . $destination)) {
208: unlink(DIR_OPENCART . $destination);
209: }
210:
211: if (file_put_contents(DIR_OPENCART . $destination, $zip->getFromIndex($i)) === false) {
212: $json['error'] = sprintf($this->language->get('error_copy'), $source, $destination);
213: }
214: }
215: }
216: }
217: }
218:
219: $zip->close();
220:
221: $json['text'] = $this->language->get('text_patch');
222:
223: $json['next'] = HTTP_CATALOG . 'install/index.php?route=upgrade/upgrade_1&version=' . $version . '&admin=' . rtrim(substr(DIR_APPLICATION, strlen(DIR_OPENCART), -1));
224: } else {
225: $json['error'] = $this->language->get('error_unzip');
226: }
227: }
228:
229: $this->response->addHeader('Content-Type: application/json');
230: $this->response->setOutput(json_encode($json));
231: }
232: }
233: