PageRenderTime 50ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/upload/admin/controller/extension/installer.php

https://github.com/daudmabena/opencart
PHP | 585 lines | 200 code | 56 blank | 329 comment | 46 complexity | 59b303351e5c903254f9aca057c57e5e MD5 | raw file
Possible License(s): GPL-3.0, MPL-2.0-no-copyleft-exception
  1. <?php
  2. class ControllerExtensionInstaller extends Controller {
  3. private $error = array();
  4. public function index() {
  5. $this->load->language('extension/installer');
  6. $this->document->setTitle($this->language->get('heading_title'));
  7. $data['heading_title'] = $this->language->get('heading_title');
  8. $data['entry_upload'] = $this->language->get('entry_upload');
  9. $data['entry_overwrite'] = $this->language->get('entry_overwrite');
  10. $data['entry_progress'] = $this->language->get('entry_progress');
  11. $data['help_upload'] = $this->language->get('help_upload');
  12. $data['button_upload'] = $this->language->get('button_upload');
  13. $data['button_clear'] = $this->language->get('button_clear');
  14. $data['button_continue'] = $this->language->get('button_continue');
  15. $data['breadcrumbs'] = array();
  16. $data['breadcrumbs'][] = array(
  17. 'text' => $this->language->get('text_home'),
  18. 'href' => $this->url->link('common/dashboard', 'token=' . $this->session->data['token'], 'SSL')
  19. );
  20. $data['breadcrumbs'][] = array(
  21. 'text' => $this->language->get('heading_title'),
  22. 'href' => $this->url->link('extension/installer', 'token=' . $this->session->data['token'], 'SSL')
  23. );
  24. $data['token'] = $this->session->data['token'];
  25. $directories = glob(DIR_DOWNLOAD . 'temp-*', GLOB_ONLYDIR);
  26. if ($directories) {
  27. $data['error_warning'] = $this->language->get('error_temporary');
  28. } else {
  29. $data['error_warning'] = '';
  30. }
  31. $data['header'] = $this->load->controller('common/header');
  32. $data['menu'] = $this->load->controller('common/menu');
  33. $data['footer'] = $this->load->controller('common/footer');
  34. $this->response->setOutput($this->load->view('extension/installer.tpl', $data));
  35. }
  36. public function upload() {
  37. $this->load->language('extension/installer');
  38. $json = array();
  39. // Check user has permission
  40. if (!$this->user->hasPermission('modify', 'extension/installer')) {
  41. $json['error'] = $this->language->get('error_permission');
  42. }
  43. if (!$json) {
  44. if (!empty($this->request->files['file']['name'])) {
  45. if (substr($this->request->files['file']['name'], -10) != '.ocmod.zip' && substr($this->request->files['file']['name'], -10) != '.ocmod.xml') {
  46. $json['error'] = $this->language->get('error_filetype');
  47. }
  48. if ($this->request->files['file']['error'] != UPLOAD_ERR_OK) {
  49. $json['error'] = $this->language->get('error_upload_' . $this->request->files['file']['error']);
  50. }
  51. } else {
  52. $json['error'] = $this->language->get('error_upload');
  53. }
  54. }
  55. if (!$json) {
  56. // If no temp directory exists create it
  57. $path = 'temp-' . md5(mt_rand());
  58. if (!is_dir(DIR_DOWNLOAD . $path)) {
  59. mkdir(DIR_DOWNLOAD . $path, 0777);
  60. }
  61. // Set the steps required for installation
  62. $json['step'] = array();
  63. $json['overwrite'] = array();
  64. if (strrchr($this->request->files['file']['name'], '.') == '.xml') {
  65. $file = DIR_DOWNLOAD . $path . '/install.xml';
  66. // If xml file copy it to the temporary directory
  67. move_uploaded_file($this->request->files['file']['tmp_name'], $file);
  68. if (file_exists($file)) {
  69. $json['step'][] = array(
  70. 'text' => $this->language->get('text_xml'),
  71. 'url' => str_replace('&amp;', '&', $this->url->link('extension/installer/xml', 'token=' . $this->session->data['token'], 'SSL')),
  72. 'path' => $path
  73. );
  74. // Clear temporary files
  75. $json['step'][] = array(
  76. 'text' => $this->language->get('text_remove'),
  77. 'url' => str_replace('&amp;', '&', $this->url->link('extension/installer/remove', 'token=' . $this->session->data['token'], 'SSL')),
  78. 'path' => $path
  79. );
  80. } else {
  81. $json['error'] = $this->language->get('error_file');
  82. }
  83. }
  84. // If zip file copy it to the temp directory
  85. if (strrchr($this->request->files['file']['name'], '.') == '.zip') {
  86. $file = DIR_DOWNLOAD . $path . '/upload.zip';
  87. move_uploaded_file($this->request->files['file']['tmp_name'], $file);
  88. if (file_exists($file)) {
  89. $zip = zip_open($file);
  90. if ($zip) {
  91. // Zip
  92. $json['step'][] = array(
  93. 'text' => $this->language->get('text_unzip'),
  94. 'url' => str_replace('&amp;', '&', $this->url->link('extension/installer/unzip', 'token=' . $this->session->data['token'], 'SSL')),
  95. 'path' => $path
  96. );
  97. // FTP
  98. $json['step'][] = array(
  99. 'text' => $this->language->get('text_ftp'),
  100. 'url' => str_replace('&amp;', '&', $this->url->link('extension/installer/ftp', 'token=' . $this->session->data['token'], 'SSL')),
  101. 'path' => $path
  102. );
  103. while ($entry = zip_read($zip)) {
  104. $zip_name = zip_entry_name($entry);
  105. // SQL
  106. if (substr($zip_name, 0, 11) == 'install.sql') {
  107. $json['step'][] = array(
  108. 'text' => $this->language->get('text_sql'),
  109. 'url' => str_replace('&amp;', '&', $this->url->link('extension/installer/sql', 'token=' . $this->session->data['token'], 'SSL')),
  110. 'path' => $path
  111. );
  112. }
  113. // XML
  114. if (substr($zip_name, 0, 11) == 'install.xml') {
  115. $json['step'][] = array(
  116. 'text' => $this->language->get('text_xml'),
  117. 'url' => str_replace('&amp;', '&', $this->url->link('extension/installer/xml', 'token=' . $this->session->data['token'], 'SSL')),
  118. 'path' => $path
  119. );
  120. }
  121. // PHP
  122. if (substr($zip_name, 0, 11) == 'install.php') {
  123. $json['step'][] = array(
  124. 'text' => $this->language->get('text_php'),
  125. 'url' => str_replace('&amp;', '&', $this->url->link('extension/installer/php', 'token=' . $this->session->data['token'], 'SSL')),
  126. 'path' => $path
  127. );
  128. }
  129. // Compare admin files
  130. $file = DIR_APPLICATION . substr($zip_name, 13);
  131. if (is_file($file) && substr($zip_name, 0, 13) == 'upload/admin/') {
  132. $json['overwrite'][] = substr($zip_name, 7);
  133. }
  134. // Compare catalog files
  135. $file = DIR_CATALOG . substr($zip_name, 7);
  136. if (is_file($file) && substr($zip_name, 0, 15) == 'upload/catalog/') {
  137. $json['overwrite'][] = substr($zip_name, 7);
  138. }
  139. // Compare image files
  140. $file = DIR_IMAGE . substr($zip_name, 13);
  141. if (is_file($file) && substr($zip_name, 0, 13) == 'upload/image/') {
  142. $json['overwrite'][] = substr($zip_name, 7);
  143. }
  144. // Compare system files
  145. $file = DIR_SYSTEM . substr($zip_name, 14);
  146. if (is_file($file) && substr($zip_name, 0, 14) == 'upload/system/') {
  147. $json['overwrite'][] = substr($zip_name, 7);
  148. }
  149. }
  150. // Clear temporary files
  151. $json['step'][] = array(
  152. 'text' => $this->language->get('text_remove'),
  153. 'url' => str_replace('&amp;', '&', $this->url->link('extension/installer/remove', 'token=' . $this->session->data['token'], 'SSL')),
  154. 'path' => $path
  155. );
  156. zip_close($zip);
  157. } else {
  158. $json['error'] = $this->language->get('error_unzip');
  159. }
  160. } else {
  161. $json['error'] = $this->language->get('error_file');
  162. }
  163. }
  164. }
  165. $this->response->setOutput(json_encode($json));
  166. }
  167. public function unzip() {
  168. $this->load->language('extension/installer');
  169. $json = array();
  170. if (!$this->user->hasPermission('modify', 'extension/installer')) {
  171. $json['error'] = $this->language->get('error_permission');
  172. }
  173. // Sanitize the filename
  174. $file = DIR_DOWNLOAD . str_replace(array('../', '..\\', '..'), '', $this->request->post['path']) . '/upload.zip';
  175. if (!file_exists($file)) {
  176. $json['error'] = $this->language->get('error_file');
  177. }
  178. if (!$json) {
  179. // Unzip the files
  180. $zip = new ZipArchive();
  181. if ($zip->open($file)) {
  182. $zip->extractTo(DIR_DOWNLOAD . str_replace(array('../', '..\\', '..'), '', $this->request->post['path']));
  183. $zip->close();
  184. } else {
  185. $json['error'] = $this->language->get('error_unzip');
  186. }
  187. // Remove Zip
  188. unlink($file);
  189. }
  190. $this->response->setOutput(json_encode($json));
  191. }
  192. public function ftp() {
  193. $this->load->language('extension/installer');
  194. $json = array();
  195. if (!$this->user->hasPermission('modify', 'extension/installer')) {
  196. $json['error'] = $this->language->get('error_permission');
  197. }
  198. $directory = DIR_DOWNLOAD . str_replace(array('../', '..\\', '..'), '', $this->request->post['path']) . '/upload/';
  199. if (!is_dir($directory)) {
  200. $json['error'] = $this->language->get('error_directory');
  201. }
  202. if (!$json) {
  203. // Get a list of files ready to upload
  204. $files = array();
  205. $path = array($directory . '*');
  206. while (count($path) != 0) {
  207. $next = array_shift($path);
  208. foreach (glob($next) as $file) {
  209. if (is_dir($file)) {
  210. $path[] = $file . '/*';
  211. }
  212. $files[] = $file;
  213. }
  214. }
  215. // Connect to the site via FTP
  216. $connection = ftp_connect($this->config->get('config_ftp_hostname'), $this->config->get('config_ftp_port'));
  217. if ($connection) {
  218. $login = ftp_login($connection, $this->config->get('config_ftp_username'), $this->config->get('config_ftp_password'));
  219. if ($login) {
  220. if ($this->config->get('config_ftp_root')) {
  221. $root = ftp_chdir($connection, $this->config->get('config_ftp_root'));
  222. } else {
  223. $root = ftp_chdir($connection, '/');
  224. }
  225. if ($root) {
  226. foreach ($files as $file) {
  227. // Upload everything in the upload directory
  228. $destination = substr($file, strlen($directory));
  229. if (is_dir($file)) {
  230. $list = ftp_nlist($connection, substr($destination, 0, strrpos($destination, '/')));
  231. if (!in_array($destination, $list)) {
  232. if (!ftp_mkdir($connection, $destination)) {
  233. $json['error'] = sprintf($this->language->get('error_ftp_directory'), $destination);
  234. }
  235. }
  236. }
  237. if (is_file($file)) {
  238. if (!ftp_put($connection, $destination, $file, FTP_BINARY)) {
  239. $json['error'] = sprintf($this->language->get('error_ftp_file'), $file);
  240. }
  241. }
  242. }
  243. } else {
  244. $json['error'] = sprintf($this->language->get('error_ftp_root'), $root);
  245. }
  246. } else {
  247. $json['error'] = sprintf($this->language->get('error_ftp_login'), $this->config->get('config_ftp_username'));
  248. }
  249. ftp_close($connection);
  250. } else {
  251. $json['error'] = sprintf($this->language->get('error_ftp_connection'), $this->config->get('config_ftp_hostname'), $this->config->get('config_ftp_port'));
  252. }
  253. }
  254. $this->response->setOutput(json_encode($json));
  255. }
  256. public function sql() {
  257. $this->load->language('extension/installer');
  258. $json = array();
  259. if (!$this->user->hasPermission('modify', 'extension/installer')) {
  260. $json['error'] = $this->language->get('error_permission');
  261. }
  262. $file = DIR_DOWNLOAD . str_replace(array('../', '..\\', '..'), '', $this->request->post['path']) . '/install.sql';
  263. if (!file_exists($file)) {
  264. $json['error'] = $this->language->get('error_file');
  265. }
  266. if (!$json) {
  267. $lines = file($file);
  268. if ($lines) {
  269. try {
  270. $sql = '';
  271. foreach ($lines as $line) {
  272. if ($line && (substr($line, 0, 2) != '--') && (substr($line, 0, 1) != '#')) {
  273. $sql .= $line;
  274. if (preg_match('/;\s*$/', $line)) {
  275. $sql = str_replace(" `oc_", " `" . DB_PREFIX, $sql);
  276. $this->db->query($sql);
  277. $sql = '';
  278. }
  279. }
  280. }
  281. } catch(Exception $exception) {
  282. $json['error'] = sprintf($this->language->get('error_exception'), $exception->getCode(), $exception->getMessage(), $exception->getFile(), $exception->getLine());
  283. }
  284. }
  285. }
  286. $this->response->setOutput(json_encode($json));
  287. }
  288. public function xml() {
  289. $this->load->language('extension/installer');
  290. $json = array();
  291. if (!$this->user->hasPermission('modify', 'extension/installer')) {
  292. $json['error'] = $this->language->get('error_permission');
  293. }
  294. $file = DIR_DOWNLOAD . str_replace(array('../', '..\\', '..'), '', $this->request->post['path']) . '/install.xml';
  295. if (!file_exists($file)) {
  296. $json['error'] = $this->language->get('error_file');
  297. }
  298. if (!$json) {
  299. $this->load->model('setting/modification');
  300. // If xml file just put it straight into the DB
  301. $xml = file_get_contents($file);
  302. if ($xml) {
  303. try {
  304. $dom = new DOMDocument('1.0', 'UTF-8');
  305. $dom->loadXml($xml);
  306. $name = $dom->getElementsByTagName('name')->item(0);
  307. if ($name) {
  308. $name = $name->nodeValue;
  309. } else {
  310. $name = '';
  311. }
  312. $author = $dom->getElementsByTagName('author')->item(0);
  313. if ($author) {
  314. $author = $author->nodeValue;
  315. } else {
  316. $author = '';
  317. }
  318. $version = $dom->getElementsByTagName('version')->item(0);
  319. if ($version) {
  320. $version = $version->nodeValue;
  321. } else {
  322. $version = '';
  323. }
  324. $link = $dom->getElementsByTagName('link')->item(0);
  325. if ($link) {
  326. $link = $link->nodeValue;
  327. } else {
  328. $link = '';
  329. }
  330. $modification_data = array(
  331. 'name' => $name,
  332. 'author' => $author,
  333. 'version' => $version,
  334. 'link' => $link,
  335. 'code' => $xml,
  336. 'status' => 1
  337. );
  338. $this->model_setting_modification->addModification($modification_data);
  339. } catch(Exception $exception) {
  340. $json['error'] = sprintf($this->language->get('error_exception'), $exception->getCode(), $exception->getMessage(), $exception->getFile(), $exception->getLine());
  341. }
  342. }
  343. }
  344. $this->response->setOutput(json_encode($json));
  345. }
  346. public function php() {
  347. $this->load->language('extension/installer');
  348. $json = array();
  349. if (!$this->user->hasPermission('modify', 'extension/installer')) {
  350. $json['error'] = $this->language->get('error_permission');
  351. }
  352. $file = DIR_DOWNLOAD . str_replace(array('../', '..\\', '..'), '', $this->request->post['path']) . '/install.php';
  353. if (!file_exists($file)) {
  354. $json['error'] = $this->language->get('error_file');
  355. }
  356. if (!$json) {
  357. try {
  358. include($file);
  359. } catch(Exception $exception) {
  360. $json['error'] = sprintf($this->language->get('error_exception'), $exception->getCode(), $exception->getMessage(), $exception->getFile(), $exception->getLine());
  361. }
  362. }
  363. $this->response->setOutput(json_encode($json));
  364. }
  365. public function remove() {
  366. $this->load->language('extension/installer');
  367. $json = array();
  368. if (!$this->user->hasPermission('modify', 'extension/installer')) {
  369. $json['error'] = $this->language->get('error_permission');
  370. }
  371. $directory = DIR_DOWNLOAD . str_replace(array('../', '..\\', '..'), '', $this->request->post['path']);
  372. if (!is_dir($directory)) {
  373. $json['error'] = $this->language->get('error_directory');
  374. }
  375. if (!$json) {
  376. // Get a list of files ready to upload
  377. $files = array();
  378. $path = array($directory . '*');
  379. while (count($path) != 0) {
  380. $next = array_shift($path);
  381. foreach (glob($next) as $file) {
  382. if (is_dir($file)) {
  383. $path[] = $file . '/*';
  384. }
  385. $files[] = $file;
  386. }
  387. }
  388. sort($files);
  389. rsort($files);
  390. foreach ($files as $file) {
  391. if (is_file($file)) {
  392. unlink($file);
  393. } elseif (is_dir($file)) {
  394. rmdir($file);
  395. }
  396. }
  397. if (file_exists($directory)) {
  398. rmdir($directory);
  399. }
  400. $json['success'] = $this->language->get('text_success');
  401. }
  402. $this->response->setOutput(json_encode($json));
  403. }
  404. public function clear() {
  405. $this->load->language('extension/installer');
  406. $json = array();
  407. if (!$this->user->hasPermission('modify', 'extension/installer')) {
  408. $json['error'] = $this->language->get('error_permission');
  409. }
  410. if (!$json) {
  411. $directories = glob(DIR_DOWNLOAD . 'temp-*', GLOB_ONLYDIR);
  412. foreach ($directories as $directory) {
  413. // Get a list of files ready to upload
  414. $files = array();
  415. $path = array($directory . '*');
  416. while (count($path) != 0) {
  417. $next = array_shift($path);
  418. foreach (glob($next) as $file) {
  419. if (is_dir($file)) {
  420. $path[] = $file . '/*';
  421. }
  422. $files[] = $file;
  423. }
  424. }
  425. sort($files);
  426. rsort($files);
  427. foreach ($files as $file) {
  428. if (is_file($file)) {
  429. unlink($file);
  430. } elseif (is_dir($file)) {
  431. rmdir($file);
  432. }
  433. }
  434. if (file_exists($directory)) {
  435. rmdir($directory);
  436. }
  437. }
  438. $json['success'] = $this->language->get('text_clear');
  439. }
  440. $this->response->setOutput(json_encode($json));
  441. }
  442. }