protected function saveUploadZip($zipFile) { // unzip with command line utility $files = array(); $dir = dirname($zipFile) . '/'; $tmpDir = $dir . '.zip_tmp/'; try { $files = wireUnzipFile($zipFile, $tmpDir); if (!count($files)) { throw new WireException($this->_('No files found in ZIP file')); } } catch (Exception $e) { $this->error($e->getMessage()); wireRmdir($tmpDir, true); unlink($zipFile); return $files; } /* OLD METHOD (for reference) $unzipCommand = self::$unzipCommand; $unzipCommand = str_replace('/src/', escapeshellarg($zipFile), $unzipCommand); $unzipCommand = str_replace('/dst/', $tmpDir, $unzipCommand); $str = exec($unzipCommand); */ $cnt = 0; foreach ($files as $file) { $pathname = $tmpDir . $file; if (!$this->isValidUpload($file, filesize($pathname), UPLOAD_ERR_OK)) { @unlink($pathname); continue; } //$destination = $dir . $file->getFilename(); $basename = $file; $basename = $this->validateFilename($basename, $this->validExtensions); if ($basename) { $destination = $dir . $basename; if (file_exists($destination) && $this->overwrite) { $bakName = $basename; do { $bakName = "_{$bakName}"; $bakDestination = $dir . $bakName; } while (file_exists($bakDestination)); rename($destination, $bakDestination); $this->wire('log')->message("Renamed {$destination} => {$bakDestination}"); $this->overwrittenFiles[$bakDestination] = $destination; } else { $destination = $this->getUniqueFilename($dir . $basename); } } else { $destination = ''; } if ($destination && rename($pathname, $destination)) { $this->completedFilenames[] = basename($destination); $cnt++; } else { @unlink($pathname); } } wireRmdir($tmpDir, true); @unlink($zipFile); if (!$cnt) { return false; } return true; }
/** * Unzip the module file to tempDir and then copy to destination directory * * @param string $file File to unzip * @param string $destinationDir Directory to copy completed files into. Optionally omit to determine automatically. * @return bool|string Returns destinationDir on success, false on failure * @throws WireException * */ public function unzipModule($file, $destinationDir = '') { $success = false; $tempDir = $this->getTempDir(); $mkdirDestination = false; try { $files = wireUnzipFile($file, $tempDir); if (is_file($file)) { unlink($file); } foreach ($files as $f) { $this->message("Extracted: {$f}", Notice::debug); } } catch (Exception $e) { $this->error($e->getMessage()); if (is_file($file)) { unlink($file); } return false; } if (!$destinationDir) { $destinationDir = $this->determineDestinationDir($files); if (!$destinationDir) { throw new WireException($this->_('Unable to find any module files')); } } $this->message("Destination directory: {$destinationDir}", Notice::debug); $files0 = trim($files[0], '/'); $extractedDir = is_dir("{$tempDir}/{$files0}") && substr($files0, 0, 1) != '.' ? "{$files0}/" : ""; // now create module directory and copy files over if (is_dir($destinationDir)) { // destination dir already there, perhaps an older version of same module? // create a backup of it $hasBackup = $this->backupDir($destinationDir); if ($hasBackup) { wireMkdir($destinationDir, true); } } else { if (wireMkdir($destinationDir, true)) { $mkdirDestination = true; } $hasBackup = false; } // label to identify destinationDir in messages and errors $dirLabel = str_replace($this->config->paths->root, '/', $destinationDir); if (is_dir($destinationDir)) { $from = $tempDir . $extractedDir; if (wireCopy($from, $destinationDir)) { $this->message($this->_('Successfully copied files to new directory:') . ' ' . $dirLabel); wireChmod($destinationDir, true); $success = true; } else { $this->error($this->_('Unable to copy files to new directory:') . ' ' . $dirLabel); if ($hasBackup) { $this->restoreDir($destinationDir); } } } else { $this->error($this->_('Could not create directory:') . ' ' . $dirLabel); } if (!$success) { $this->error($this->_('Unable to copy module files:') . ' ' . $dirLabel); if ($mkdirDestination && !wireRmdir($destinationDir, true)) { $this->error($this->_('Could not delete failed module dir:') . ' ' . $destinationDir, Notice::log); } } return $success ? $destinationDir : false; }