/** * @param $expectedResult * @param $dirs * @param $files * @param $expectedKey */ public function _doGuessBaseDir($expectedResult, $dirs, $files, $expectedKey) { $this->file = tempnam(sys_get_temp_dir(), 'testzip-'); $this->assertTrue(CRM_Utils_Zip::createTestZip($this->file, $dirs, $files)); $zip = new ZipArchive(); $this->assertTrue($zip->open($this->file)); $this->assertEquals($expectedResult, CRM_Utils_Zip::guessBaseDir($zip, $expectedKey)); }
/** * Determine the name of the folder within a zip * * @param ZipArchive $zip * @param $expected * * @return string or FALSE */ public static function guessBasedir(ZipArchive $zip, $expected) { $candidate = FALSE; $basedirs = CRM_Utils_Zip::findBaseDirs($zip); if (in_array($expected, $basedirs)) { $candidate = $expected; } elseif (count($basedirs) == 1) { $candidate = array_shift($basedirs); } if ($candidate !== FALSE && preg_match('/^[a-zA-Z0-9]/', $candidate)) { return $candidate; } else { return FALSE; } }
/** * Extract an extension from a zip file. * * @param string $key * The name of the extension being installed; this usually matches the basedir in the .zip. * @param string $zipFile * The local path to a .zip file. * @return string|FALSE * zip file path */ public function extractFiles($key, $zipFile) { $config = CRM_Core_Config::singleton(); $zip = new ZipArchive(); $res = $zip->open($zipFile); if ($res === TRUE) { $zipSubDir = CRM_Utils_Zip::guessBasedir($zip, $key); if ($zipSubDir === FALSE) { CRM_Core_Session::setStatus(ts('Unable to extract the extension: bad directory structure'), '', 'error'); return FALSE; } $extractedZipPath = $this->tmpDir . DIRECTORY_SEPARATOR . $zipSubDir; if (is_dir($extractedZipPath)) { if (!CRM_Utils_File::cleanDir($extractedZipPath, TRUE, FALSE)) { CRM_Core_Session::setStatus(ts('Unable to extract the extension: %1 cannot be cleared', array(1 => $extractedZipPath)), ts('Installation Error'), 'error'); return FALSE; } } if (!$zip->extractTo($this->tmpDir)) { CRM_Core_Session::setStatus(ts('Unable to extract the extension to %1.', array(1 => $this->tmpDir)), ts('Installation Error'), 'error'); return FALSE; } $zip->close(); } else { CRM_Core_Session::setStatus(ts('Unable to extract the extension.'), '', 'error'); return FALSE; } return $extractedZipPath; }
public function installFiles() { $config = CRM_Core_Config::singleton(); $zip = new ZipArchive(); $res = $zip->open($this->tmpFile); if ($res === TRUE) { $zipSubDir = CRM_Utils_Zip::guessBasedir($zip, $this->key); if ($zipSubDir === FALSE) { CRM_Core_Session::setStatus(ts('Unable to extract the extension: bad directory structure') . '<br/>'); return FALSE; } $path = $config->extensionsDir . DIRECTORY_SEPARATOR . 'tmp'; $extractedZipPath = $path . DIRECTORY_SEPARATOR . $zipSubDir; if (is_dir($extractedZipPath)) { if (!CRM_Utils_File::cleanDir($extractedZipPath, TRUE, FALSE)) { CRM_Core_Session::setStatus(ts('Unable to extract the extension: %1 cannot be cleared', array(1 => $extractedZipPath)) . '<br/>'); return FALSE; } } if (!$zip->extractTo($path)) { CRM_Core_Session::setStatus(ts('Unable to extract the extension to %1.', array(1 => $path)) . '<br/>'); return FALSE; } $zip->close(); } else { CRM_Core_Session::setStatus('Unable to extract the extension.'); return FALSE; } $filename = $extractedZipPath . DIRECTORY_SEPARATOR . 'info.xml'; if (!is_readable($filename)) { CRM_Core_Session::setStatus(ts('Failed reading data from %1 during installation', array(1 => $filename)) . '<br/>'); return FALSE; } $newxml = file_get_contents($filename); if (empty($newxml)) { CRM_Core_Session::setStatus(ts('Failed reading data from %1 during installation', array(1 => $filename)) . '<br/>'); return FALSE; } $check = new CRM_Core_Extensions_Extension($this->key . ".newversion"); $check->readXMLInfo($newxml); if ($check->version != $this->version) { CRM_Core_Error::fatal('Cannot install - there are differences between extdir XML file and archive XML file!'); } // Why is this a copy instead of a move? CRM_Utils_File::copyDir($extractedZipPath, $config->extensionsDir . DIRECTORY_SEPARATOR . $this->key); if (!CRM_Utils_File::cleanDir($extractedZipPath, TRUE, FALSE)) { CRM_Core_Session::setStatus(ts('Failed to clean temp dir: %1', array(1 => $extractedZipPath)) . '<br/>'); } return TRUE; }