/**
  * 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;
 }