install.php (14915B)
1 <?php 2 class ControllerMarketplaceInstall extends Controller { 3 public function install() { 4 $this->load->language('marketplace/install'); 5 6 $json = array(); 7 8 if (isset($this->request->get['extension_install_id'])) { 9 $extension_install_id = $this->request->get['extension_install_id']; 10 } else { 11 $extension_install_id = 0; 12 } 13 14 if (!$this->user->hasPermission('modify', 'marketplace/install')) { 15 $json['error'] = $this->language->get('error_permission'); 16 } 17 18 // Make sure the file name is stored in the session. 19 if (!isset($this->session->data['install'])) { 20 $json['error'] = $this->language->get('error_file'); 21 } elseif (!is_file(DIR_UPLOAD . $this->session->data['install'] . '.tmp')) { 22 $json['error'] = $this->language->get('error_file'); 23 } 24 25 if (!$json) { 26 $json['text'] = $this->language->get('text_unzip'); 27 28 $json['next'] = str_replace('&', '&', $this->url->link('marketplace/install/unzip', 'user_token=' . $this->session->data['user_token'] . '&extension_install_id=' . $extension_install_id, true)); 29 } 30 31 $this->response->addHeader('Content-Type: application/json'); 32 $this->response->setOutput(json_encode($json)); 33 } 34 35 public function unzip() { 36 $this->load->language('marketplace/install'); 37 38 $json = array(); 39 40 if (isset($this->request->get['extension_install_id'])) { 41 $extension_install_id = $this->request->get['extension_install_id']; 42 } else { 43 $extension_install_id = 0; 44 } 45 46 if (!$this->user->hasPermission('modify', 'marketplace/install')) { 47 $json['error'] = $this->language->get('error_permission'); 48 } 49 50 if (!isset($this->session->data['install'])) { 51 $json['error'] = $this->language->get('error_file'); 52 } elseif (!is_file(DIR_UPLOAD . $this->session->data['install'] . '.tmp')) { 53 $json['error'] = $this->language->get('error_file'); 54 } 55 56 // Sanitize the filename 57 if (!$json) { 58 $file = DIR_UPLOAD . $this->session->data['install'] . '.tmp'; 59 60 // Unzip the files 61 $zip = new ZipArchive(); 62 63 if ($zip->open($file)) { 64 $zip->extractTo(DIR_UPLOAD . 'tmp-' . $this->session->data['install']); 65 $zip->close(); 66 } else { 67 $json['error'] = $this->language->get('error_unzip'); 68 } 69 70 // Remove Zip 71 unlink($file); 72 73 $json['text'] = $this->language->get('text_move'); 74 75 $json['next'] = str_replace('&', '&', $this->url->link('marketplace/install/move', 'user_token=' . $this->session->data['user_token'] . '&extension_install_id=' . $extension_install_id, true)); 76 } 77 78 $this->response->addHeader('Content-Type: application/json'); 79 $this->response->setOutput(json_encode($json)); 80 } 81 82 public function move() { 83 $this->load->language('marketplace/install'); 84 85 $json = array(); 86 87 if (isset($this->request->get['extension_install_id'])) { 88 $extension_install_id = $this->request->get['extension_install_id']; 89 } else { 90 $extension_install_id = 0; 91 } 92 93 if (!$this->user->hasPermission('modify', 'marketplace/install')) { 94 $json['error'] = $this->language->get('error_permission'); 95 } 96 97 if (!isset($this->session->data['install'])) { 98 $json['error'] = $this->language->get('error_directory'); 99 } elseif (!is_dir(DIR_UPLOAD . 'tmp-' . $this->session->data['install'] . '/')) { 100 $json['error'] = $this->language->get('error_directory'); 101 } 102 103 if (!$json) { 104 $directory = DIR_UPLOAD . 'tmp-' . $this->session->data['install'] . '/'; 105 106 if (is_dir($directory . 'upload/')) { 107 $files = array(); 108 109 // Get a list of files ready to upload 110 $path = array($directory . 'upload/*'); 111 112 while (count($path) != 0) { 113 $next = array_shift($path); 114 115 foreach ((array)glob($next) as $file) { 116 if (is_dir($file)) { 117 $path[] = $file . '/*'; 118 } 119 120 $files[] = $file; 121 } 122 } 123 124 // A list of allowed directories to be written to 125 $allowed = array( 126 'admin/controller/extension/', 127 'admin/language/', 128 'admin/model/extension/', 129 'admin/view/image/', 130 'admin/view/javascript/', 131 'admin/view/stylesheet/', 132 'admin/view/template/extension/', 133 'catalog/controller/extension/', 134 'catalog/language/', 135 'catalog/model/extension/', 136 'catalog/view/javascript/', 137 'catalog/view/theme/', 138 'system/config/', 139 'system/library/', 140 'image/catalog/' 141 ); 142 143 // First we need to do some checks 144 foreach ($files as $file) { 145 $destination = str_replace('\\', '/', substr($file, strlen($directory . 'upload/'))); 146 147 $safe = false; 148 149 foreach ($allowed as $value) { 150 if (strlen($destination) < strlen($value) && substr($value, 0, strlen($destination)) == $destination) { 151 $safe = true; 152 153 break; 154 } 155 156 if (strlen($destination) > strlen($value) && substr($destination, 0, strlen($value)) == $value) { 157 $safe = true; 158 159 break; 160 } 161 } 162 163 if ($safe) { 164 // Check if the copy location exists or not 165 if (substr($destination, 0, 5) == 'admin') { 166 $destination = DIR_APPLICATION . substr($destination, 6); 167 } 168 169 if (substr($destination, 0, 7) == 'catalog') { 170 $destination = DIR_CATALOG . substr($destination, 8); 171 } 172 173 if (substr($destination, 0, 5) == 'image') { 174 $destination = DIR_IMAGE . substr($destination, 6); 175 } 176 177 if (substr($destination, 0, 6) == 'system') { 178 $destination = DIR_SYSTEM . substr($destination, 7); 179 } 180 } else { 181 $json['error'] = sprintf($this->language->get('error_allowed'), $destination); 182 183 break; 184 } 185 } 186 187 if (!$json) { 188 $this->load->model('setting/extension'); 189 190 foreach ($files as $file) { 191 $destination = str_replace('\\', '/', substr($file, strlen($directory . 'upload/'))); 192 193 $path = ''; 194 195 if (substr($destination, 0, 5) == 'admin') { 196 $path = DIR_APPLICATION . substr($destination, 6); 197 } 198 199 if (substr($destination, 0, 7) == 'catalog') { 200 $path = DIR_CATALOG . substr($destination, 8); 201 } 202 203 if (substr($destination, 0, 5) == 'image') { 204 $path = DIR_IMAGE . substr($destination, 6); 205 } 206 207 if (substr($destination, 0, 6) == 'system') { 208 $path = DIR_SYSTEM . substr($destination, 7); 209 } 210 211 if (is_dir($file) && !is_dir($path)) { 212 if (mkdir($path, 0777)) { 213 $this->model_setting_extension->addExtensionPath($extension_install_id, $destination); 214 } 215 } 216 217 if (is_file($file)) { 218 if (rename($file, $path)) { 219 $this->model_setting_extension->addExtensionPath($extension_install_id, $destination); 220 } 221 } 222 } 223 } 224 } 225 } 226 227 if (!$json) { 228 $json['text'] = $this->language->get('text_xml'); 229 230 $json['next'] = str_replace('&', '&', $this->url->link('marketplace/install/xml', 'user_token=' . $this->session->data['user_token'] . '&extension_install_id=' . $extension_install_id, true)); 231 } 232 233 $this->response->addHeader('Content-Type: application/json'); 234 $this->response->setOutput(json_encode($json)); 235 } 236 237 public function xml() { 238 $this->load->language('marketplace/install'); 239 240 $json = array(); 241 242 if (isset($this->request->get['extension_install_id'])) { 243 $extension_install_id = $this->request->get['extension_install_id']; 244 } else { 245 $extension_install_id = 0; 246 } 247 248 if (!$this->user->hasPermission('modify', 'marketplace/install')) { 249 $json['error'] = $this->language->get('error_permission'); 250 } 251 252 if (!isset($this->session->data['install'])) { 253 $json['error'] = $this->language->get('error_directory'); 254 } elseif (!is_dir(DIR_UPLOAD . 'tmp-' . $this->session->data['install'] . '/')) { 255 $json['error'] = $this->language->get('error_directory'); 256 } 257 258 if (!$json) { 259 $file = DIR_UPLOAD . 'tmp-' . $this->session->data['install'] . '/install.xml'; 260 261 if (is_file($file)) { 262 $this->load->model('setting/modification'); 263 264 // If xml file just put it straight into the DB 265 $xml = file_get_contents($file); 266 267 if ($xml) { 268 try { 269 $dom = new DOMDocument('1.0', 'UTF-8'); 270 $dom->loadXml($xml); 271 272 $name = $dom->getElementsByTagName('name')->item(0); 273 274 if ($name) { 275 $name = $name->nodeValue; 276 } else { 277 $name = ''; 278 } 279 280 $code = $dom->getElementsByTagName('code')->item(0); 281 282 if ($code) { 283 $code = $code->nodeValue; 284 285 // Check to see if the modification is already installed or not. 286 $modification_info = $this->model_setting_modification->getModificationByCode($code); 287 288 if ($modification_info) { 289 $this->model_setting_modification->deleteModification($modification_info['modification_id']); 290 } 291 } else { 292 $json['error'] = $this->language->get('error_code'); 293 } 294 295 $author = $dom->getElementsByTagName('author')->item(0); 296 297 if ($author) { 298 $author = $author->nodeValue; 299 } else { 300 $author = ''; 301 } 302 303 $version = $dom->getElementsByTagName('version')->item(0); 304 305 if ($version) { 306 $version = $version->nodeValue; 307 } else { 308 $version = ''; 309 } 310 311 $link = $dom->getElementsByTagName('link')->item(0); 312 313 if ($link) { 314 $link = $link->nodeValue; 315 } else { 316 $link = ''; 317 } 318 319 if (!$json) { 320 321 322 $modification_data = array( 323 'extension_install_id' => $extension_install_id, 324 'name' => $name, 325 'code' => $code, 326 'author' => $author, 327 'version' => $version, 328 'link' => $link, 329 'xml' => $xml, 330 'status' => 1 331 ); 332 333 $this->model_setting_modification->addModification($modification_data); 334 } 335 } catch(Exception $exception) { 336 $json['error'] = sprintf($this->language->get('error_exception'), $exception->getCode(), $exception->getMessage(), $exception->getFile(), $exception->getLine()); 337 } 338 } 339 } 340 } 341 342 if (!$json) { 343 $json['text'] = $this->language->get('text_remove'); 344 345 $json['next'] = str_replace('&', '&', $this->url->link('marketplace/install/remove', 'user_token=' . $this->session->data['user_token'], true)); 346 } 347 348 $this->response->addHeader('Content-Type: application/json'); 349 $this->response->setOutput(json_encode($json)); 350 } 351 352 public function remove() { 353 $this->load->language('marketplace/install'); 354 355 $json = array(); 356 357 if (!$this->user->hasPermission('modify', 'marketplace/install')) { 358 $json['error'] = $this->language->get('error_permission'); 359 } 360 361 if (!isset($this->session->data['install'])) { 362 $json['error'] = $this->language->get('error_directory'); 363 } 364 365 if (!$json) { 366 $directory = DIR_UPLOAD . 'tmp-' . $this->session->data['install'] . '/'; 367 368 if (is_dir($directory)) { 369 // Get a list of files ready to upload 370 $files = array(); 371 372 $path = array($directory); 373 374 while (count($path) != 0) { 375 $next = array_shift($path); 376 377 // We have to use scandir function because glob will not pick up dot files. 378 foreach (array_diff(scandir($next), array('.', '..')) as $file) { 379 $file = $next . '/' . $file; 380 381 if (is_dir($file)) { 382 $path[] = $file; 383 } 384 385 $files[] = $file; 386 } 387 } 388 389 rsort($files); 390 391 foreach ($files as $file) { 392 if (is_file($file)) { 393 unlink($file); 394 } elseif (is_dir($file)) { 395 rmdir($file); 396 } 397 } 398 399 if (is_dir($directory)) { 400 rmdir($directory); 401 } 402 } 403 404 $file = DIR_UPLOAD . $this->session->data['install'] . '.tmp'; 405 406 if (is_file($file)) { 407 unlink($file); 408 } 409 410 $json['success'] = $this->language->get('text_success'); 411 } 412 413 $this->response->addHeader('Content-Type: application/json'); 414 $this->response->setOutput(json_encode($json)); 415 } 416 417 public function uninstall() { 418 $this->load->language('marketplace/install'); 419 420 $json = array(); 421 422 if (isset($this->request->get['extension_install_id'])) { 423 $extension_install_id = $this->request->get['extension_install_id']; 424 } else { 425 $extension_install_id = 0; 426 } 427 428 if (!$this->user->hasPermission('modify', 'marketplace/install')) { 429 $json['error'] = $this->language->get('error_permission'); 430 } 431 432 if (!$json) { 433 $this->load->model('setting/extension'); 434 435 $results = $this->model_setting_extension->getExtensionPathsByExtensionInstallId($extension_install_id); 436 437 rsort($results); 438 439 foreach ($results as $result) { 440 $source = ''; 441 442 // Check if the copy location exists or not 443 if (substr($result['path'], 0, 5) == 'admin') { 444 $source = DIR_APPLICATION . substr($result['path'], 6); 445 } 446 447 if (substr($result['path'], 0, 7) == 'catalog') { 448 $source = DIR_CATALOG . substr($result['path'], 8); 449 } 450 451 if (substr($result['path'], 0, 5) == 'image') { 452 $source = DIR_IMAGE . substr($result['path'], 6); 453 } 454 455 if (substr($result['path'], 0, 14) == 'system/library') { 456 $source = DIR_SYSTEM . 'library/' . substr($result['path'], 15); 457 } 458 459 if (is_file($source)) { 460 unlink($source); 461 } 462 463 if (is_dir($source)) { 464 // Get a list of files ready to upload 465 $files = array(); 466 467 $path = array($source); 468 469 while (count($path) != 0) { 470 $next = array_shift($path); 471 472 // We have to use scandir function because glob will not pick up dot files. 473 foreach (array_diff(scandir($next), array('.', '..')) as $file) { 474 $file = $next . '/' . $file; 475 476 if (is_dir($file)) { 477 $path[] = $file; 478 } 479 480 $files[] = $file; 481 } 482 } 483 484 rsort($files); 485 486 foreach ($files as $file) { 487 if (is_file($file)) { 488 unlink($file); 489 } elseif (is_dir($file)) { 490 rmdir($file); 491 } 492 } 493 494 if (is_file($source)) { 495 unlink($source); 496 } 497 498 if (is_dir($source)) { 499 rmdir($source); 500 } 501 } 502 503 $this->model_setting_extension->deleteExtensionPath($result['extension_path_id']); 504 } 505 506 // Remove the install 507 $this->model_setting_extension->deleteExtensionInstall($extension_install_id); 508 509 // Remove any xml modifications 510 $this->load->model('setting/modification'); 511 512 $this->model_setting_modification->deleteModificationsByExtensionInstallId($extension_install_id); 513 514 $json['success'] = $this->language->get('text_success'); 515 } 516 517 $this->response->addHeader('Content-Type: application/json'); 518 $this->response->setOutput(json_encode($json)); 519 } 520 }