public static function DeflateZip($pathToZip, $extractToDir, array $filesArray = null) { if (is_null($pathToZip)) { throw new Exception('Path to ZIP is null'); } $zip = new ZipArchive(); $zipResource = $zip->open($pathToZip); // Workaround for https://github.com/facebook/hhvm/issues/1804 foreach ($filesArray as $file) { $dir = dirname("{$extractToDir}/{$file}"); if (!is_dir($dir)) { mkdir($dir, 0755, true); } } if ($zipResource === true) { if (!$zip->extractTo($extractToDir, $filesArray)) { throw new Exception('Error extracting zip.'); } $zip->close(); } else { throw new Exception('Error opening zip file: ' . ZipHandler::ErrorMessage($zipResource)); } }
/** * Entry point for zip validation * Determines the type of problem we are deploying * * @return boolean * @throws InvalidParameterException */ private function validateZip() { $this->log->info('Validating zip...'); if (!array_key_exists('problem_contents', $_FILES)) { $this->log->error('\\$_FILES global does not contain problem_contents.'); throw new InvalidParameterException('parameterEmpty', 'problem_contents'); } if (isset($_FILES['problem_contents']) && !FileHandler::GetFileUploader()->IsUploadedFile($_FILES['problem_contents']['tmp_name'])) { $this->log->error("GetFileUploader()->IsUploadedFile() check failed for \$_FILES['problem_contents']['tmp_name']."); throw new InvalidParameterException('parameterEmpty', 'problem_contents'); } $this->filesToUnzip = array(); $this->imageHashes = array(); $this->casesFiles = array(); $this->zipPath = $_FILES['problem_contents']['tmp_name']; $this->log->info("Opening {$this->zipPath}..."); $zip = new ZipArchive(); $resource = $zip->open($this->zipPath); $size = 0; if ($resource !== true) { $this->log->error('Unable to open zip file: ' . ZipHandler::ErrorMessage($resource)); throw new InvalidParameterException('problemDeployerCorruptZip'); } // Get list of files for ($i = 0; $i < $zip->numFiles; $i++) { $this->log->info("Found inside zip: '" . $zip->getNameIndex($i) . "'"); $zipFilesArray[] = $zip->getNameIndex($i); // Sum up the size $statI = $zip->statIndex($i); $size += $statI['size']; // If the file is THE validator for custom outputs... if (stripos($zip->getNameIndex($i), 'validator.') === 0) { $this->hasValidator = true; $this->filesToUnzip[] = $zip->getNameIndex($i); $this->log->info('Validator found: ' . $zip->getNameIndex($i)); } // Interactive problems. if (stripos($zip->getNameIndex($i), 'interactive/') === 0) { $this->filesToUnzip[] = $zip->getNameIndex($i); $this->isInteractive = true; if (ProblemDeployer::endsWith($zip->getNameIndex($i), '.idl', true)) { $this->log->info('.idl file found: ' . $zip->getNameIndex($i)); $this->idlFile = $zip->getNameIndex($i); } } // Example inputs. if (stripos($zip->getNameIndex($i), 'examples/') === 0 && ProblemDeployer::endsWith($zip->getNameIndex($i), '.in', true)) { $this->filesToUnzip[] = $zip->getNameIndex($i); } } $this->checkedForInteractive = true; if ($this->isInteractive) { if ($this->idlFile == null) { throw new InvalidParameterException('problemDeployerIdlMissing'); } elseif (!in_array('interactive/examples/sample.in', $this->filesToUnzip)) { throw new InvalidParameterException('problemDeployerInteractiveSampleMissing'); } } if ($this->isInteractive && $size > ProblemDeployer::MAX_INTERACTIVE_ZIP_FILESIZE) { throw new InvalidParameterException('problemDeployerExceededZipSizeLimit', null, array('size' => $size, 'max_size' => ProblemDeployer::MAX_INTERACTIVE_ZIP_FILESIZE)); } elseif ($size > ProblemDeployer::MAX_ZIP_FILESIZE) { throw new InvalidParameterException('problemDeployerExceededZipSizeLimit', null, array('size' => $size, 'max_size' => ProblemDeployer::MAX_ZIP_FILESIZE)); } try { // Look for testplan if (in_array('testplan', $zipFilesArray)) { $returnValue = $this->checkCasesWithTestplan($zip, $zipFilesArray); $this->log->info('testplan found, checkCasesWithTestPlan=' . $returnValue); $this->filesToUnzip[] = 'testplan'; } else { $this->log->info('testplan not found'); $this->checkCases($zip, $zipFilesArray); } // Log files to unzip $this->log->info('Files to unzip: '); foreach ($this->filesToUnzip as $file) { $this->log->info($file); } // Look for statements $returnValue = $this->checkProblemStatements($zipFilesArray, $zip); $this->log->info('checkProblemStatements=' . $returnValue . '.'); } finally { // Close zip $this->log->info('closing zip'); $zip->close(); } return $returnValue; }