private function unzip($file) { $zip = new fileUnzip($file); if ($zip->isEmpty()) { $zip->close(); return false; //throw new Exception(__('File is empty or not a compressed file.')); } foreach ($zip->getFilesList() as $zip_file) { # Check zipped file name if (substr($zip_file, -4) != '.txt') { continue; } # Check zipped file contents $content = $zip->unzip($zip_file); if (strpos($content, '///DOTCLEAR|') !== 0) { unset($content); continue; } $target = path::fullFromRoot($zip_file, dirname($file)); # Check existing files with same name if (file_exists($target)) { $zip->close(); unset($content); throw new Exception(__('Another file with same name exists.')); } # Extract backup content if (file_put_contents($target, $content) === false) { $zip->close(); unset($content); throw new Exception(__('Failed to extract backup file.')); } $zip->close(); unset($content); # Return extracted file name return $target; } $zip->close(); throw new Exception(__('No backup in compressed file.')); }
/** * Upgrade process. * * @param string $sZipFile * @param string $sZipDigests * @param string $sZipRoot * @param string $sRoot * @param string $sRootDigests * @throws Exception */ public function performUpgrade($sZipFile, $sZipDigests, $sZipRoot, $sRoot, $sRootDigests) { if (!is_readable($sZipFile)) { throw new Exception(__('Archive not found.')); } if (!is_readable($sRootDigests)) { @unlink($sZipFile); throw new Exception(__('Unable to read current digests file.')); } $oZip = new fileUnzip($sZipFile); if (!$oZip->hasFile($sZipDigests)) { @unlink($sZipFile); throw new Exception(__('Downloaded file does not seem to be a valid archive.')); } # force /install dir foreach ($oZip->getFilesList() as $sFile) { $sFile = str_replace($sZipRoot . '/', '', $sFile); if (substr($sFile, 0, 7) == 'install') { $this->setForcedFile($sFile); } } $opts = FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES; $cur_digests = file($sRootDigests, $opts); $new_digests = explode("\n", $oZip->unzip($sZipDigests)); $aNewFiles = self::getNewFiles($cur_digests, $new_digests); if (!empty($this->aForcedFiles)) { $aNewFiles = array_merge($aNewFiles, $this->aForcedFiles); } $aZipFiles = array(); $aNotWritable = array(); foreach ($aNewFiles as $file) { if (!$file) { continue; } if (!$oZip->hasFile($sZipRoot . '/' . $file)) { @unlink($sZipFile); throw new Exception(__('c_a_update_incomplete_archive')); } $sDest = $sDest_dir = $sRoot . '/' . $file; while (!is_dir($sDest_dir = dirname($sDest_dir))) { } if (file_exists($sDest) && !is_writable($sDest) || !file_exists($sDest) && !is_writable($sDest_dir)) { $aNotWritable[] = $file; continue; } $aZipFiles[] = $file; } # If only one file is not writable, stop everything now if (!empty($aNotWritable)) { $e = new Exception('Some files are not writable', self::ERR_FILES_UNWRITALBE); $e->bad_files = $aNotWritable; throw $e; } # Everything's fine, we can write files, then do it now $can_touch = function_exists('touch'); foreach ($aZipFiles as $file) { $oZip->unzip($sZipRoot . '/' . $file, $sRoot . '/' . $file); if ($can_touch) { @touch($sRoot . '/' . $file); } } @unlink($sZipFile); }
private static function installLocalWidget($categoryId, $userId, $uploadedFilePath) { try { $unziper = new fileUnzip($uploadedFilePath); $archiveContent = $unziper->getFilesList(); $tempFolder = './widgets/' . mktime(); $alreadyInstalled = false; if (!self::isFileInArchive($archiveContent, 'config.xml')) { throw new FileException(MwwException::MODEL, 'Unable to find config.xml in the provided archive'); } else { if (!self::isFileInArchive($archiveContent, 'index.html') && !self::isFileInArchive($archiveContent, 'index.xul')) { throw new FileException(MwwException::MODEL, 'Unable to find index.html in the provided archive'); } else { // The mandatory files are in the archive. // We unzip the document in the widget repository under an arbitrary folder. $unziper->unzipAll($tempFolder); $unziper->close(); // parse the manifest. $manifestPath = $tempFolder . '/config.xml'; $doc = new DOMDocument(); $doc->preserveWhiteSpace = false; if (!@$doc->load($manifestPath)) { throw new XMLParsingException(MwwException::MODEL, 'Unable to parse XML file. Document not well formed.'); } // validate the manifest. if (!@$doc->schemaValidate('./schema/manifest.xsd')) { throw new XMLValidationException(MwwException::MODEL, "The XML File isn't valid according to the XML Schema."); } // test if the id is unique (test if the directory exists). $id = $doc->getElementsByTagName('widget')->item(0)->getAttribute('id'); // getting name/title of the widget. if ($doc->getElementsByTagName('name')->length) { $name = $doc->getElementsByTagName('name')->item(0)->nodeValue; } else { if ($doc->getElementsByTagName('title')->length) { $name = $doc->getElementsByTagName('title')->item(0)->nodeValue; } else { throw new XMLValidationException(MwwException::MODEL, "The XML File is not valid. The mandatory title or name element is missing."); } } // getting widget description. $description = null; if ($doc->getElementsByTagName('description')->length) { $description = $doc->getElementsByTagName('description')->item(0)->nodeValue; } // is widget authentication enabled or disabled ? $widgetAuth = false; $authKey = null; if ($doc->getElementsByTagName('widget_authentication')->length) { $authValue = $doc->getElementsByTagName('widget_authentication')->item(0)->nodeValue; if ($authValue == 'enabled') { $widgetAuth = true; // create the key. $crypto = new Rijndael(); $authKey = $crypto->generateKey(); } } $targetFolder = './widgets/' . $id; if (file_exists($targetFolder)) { $alreadyInstalled = true; throw new FileException(MwwException::MODEL, 'A widget with the id \'' . $id . '\' already exists.'); } // create the widget directory (actually we simply rename the temporary directory). if (!@rename($tempFolder, $targetFolder)) { throw new FileException(MwwException::MODEL, 'The widget directory could not be created'); } $nameToReturn = $name; // -- Persistant data access section. $db = DbUtil::accessFactory(); $categoryId = $categoryId != 0 ? $db->escape($categoryId) : 'NULL'; $userId = $db->escape($userId); $name = $db->escape($name); $description = $db->escape($description); $generatedKey = $widgetAuth ? "'{$authKey}'" : 'NULL'; // insert the widget into the database. if (!$db->execute("INSERT INTO `widgets` (`widgetid`, `widgetname`, `visible`, `copname`, `category`, `description`, `authkey`) VALUES ('{$id}', '{$name}', 0, (SELECT `copname` FROM `users` WHERE `id`= {$userId}), {$categoryId}, '{$description}', {$generatedKey})")) { throw new DBException(MwwException::MODEL, "Unable to insert new widget '{$id}' information in persistant data"); } // -- End of Persistant data access section. // End of the installation. Everything was fine. return $nameToReturn; } } } catch (Exception $ex) { if (isset($tempFolder) && is_dir($tempFolder)) { Util::full_rmdir($tempFolder); } if (isset($targetFolder) && is_dir($targetFolder) && !$alreadyInstalled) { Util::full_rmdir($targetFolder); } throw $ex; } }