Exemplo n.º 1
0
 /**
  * Saves the source of this template.
  * 
  * @param	string		$source
  */
 public function setSource($source)
 {
     $path = $this->getPath();
     // create dir
     $folder = dirname($path);
     if (!file_exists($folder)) {
         mkdir($folder, 0777);
     }
     // set source
     $file = new File($path);
     $file->write($source);
     $file->close();
     FileUtil::makeWritable($path);
 }
Exemplo n.º 2
0
 /**
  * Rebuilds the option file.
  */
 public static function rebuild()
 {
     $writer = new AtomicWriter(WCF_DIR . 'options.inc.php');
     // file header
     $writer->write("<?php\n/**\n* generated at " . gmdate('r') . "\n*/\n");
     // get all options
     $options = Option::getOptions();
     foreach ($options as $optionName => $option) {
         $writer->write("if (!defined('" . $optionName . "')) define('" . $optionName . "', " . ($option->optionType == 'boolean' || $option->optionType == 'integer' ? intval($option->optionValue) : "'" . addcslashes($option->optionValue, "'\\") . "'") . ");\n");
     }
     unset($options);
     // file footer
     $writer->write("\n");
     $writer->flush();
     $writer->close();
     FileUtil::makeWritable(WCF_DIR . 'options.inc.php');
     WCF::resetZendOpcache(WCF_DIR . 'options.inc.php');
 }
 /**
  * @see	\wcf\form\IForm::save()
  */
 public function save()
 {
     // write master password file
     $file = new File(WCF_DIR . 'acp/masterPassword.inc.php');
     $file->write("<?php\n/** MASTER PASSWORD STORAGE\nDO NOT EDIT THIS FILE */\ndefine('MASTER_PASSWORD', '" . PasswordUtil::getDoubleSaltedHash($this->masterPassword) . "');\n?>");
     $file->close();
     FileUtil::makeWritable(WCF_DIR . 'acp/masterPassword.inc.php');
     parent::save();
 }
Exemplo n.º 4
0
 /**
  * Exports this style.
  * 
  * @param	boolean		$templates
  * @param	boolean		$images
  * @param	string		$packageName
  */
 public function export($templates = false, $images = false, $packageName = '')
 {
     // create style tar
     $styleTarName = FileUtil::getTemporaryFilename('style_', '.tgz');
     $styleTar = new TarWriter($styleTarName, true);
     // append style preview image
     if ($this->image && @file_exists(WCF_DIR . 'images/' . $this->image)) {
         $styleTar->add(WCF_DIR . 'images/' . $this->image, '', FileUtil::addTrailingSlash(dirname(WCF_DIR . 'images/' . $this->image)));
     }
     // fetch style description
     $sql = "SELECT\t\tlanguage.languageCode, language_item.languageItemValue\n\t\t\tFROM\t\twcf" . WCF_N . "_language_item language_item\n\t\t\tLEFT JOIN\twcf" . WCF_N . "_language language\n\t\t\tON\t\t(language.languageID = language_item.languageID)\n\t\t\tWHERE\t\tlanguage_item.languageItem = ?";
     $statement = WCF::getDB()->prepareStatement($sql);
     $statement->execute(array($this->styleDescription));
     $styleDescriptions = array();
     while ($row = $statement->fetchArray()) {
         $styleDescriptions[$row['languageCode']] = $row['languageItemValue'];
     }
     // create style info file
     $xml = new XMLWriter();
     $xml->beginDocument('style', 'http://www.woltlab.com', 'http://www.woltlab.com/XSD/maelstrom/style.xsd');
     // general block
     $xml->startElement('general');
     $xml->writeElement('stylename', $this->styleName);
     // style description
     foreach ($styleDescriptions as $languageCode => $value) {
         $xml->writeElement('description', $value, array('language' => $languageCode));
     }
     $xml->writeElement('date', $this->styleDate);
     $xml->writeElement('version', $this->styleVersion);
     if ($this->image) {
         $xml->writeElement('image', $this->image);
     }
     if ($this->copyright) {
         $xml->writeElement('copyright', $this->copyright);
     }
     if ($this->license) {
         $xml->writeElement('license', $this->license);
     }
     $xml->endElement();
     // author block
     $xml->startElement('author');
     $xml->writeElement('authorname', $this->authorName);
     if ($this->authorURL) {
         $xml->writeElement('authorurl', $this->authorURL);
     }
     $xml->endElement();
     // files block
     $xml->startElement('files');
     $xml->writeElement('variables', 'variables.xml');
     if ($templates) {
         $xml->writeElement('templates', 'templates.tar');
     }
     if ($images) {
         $xml->writeElement('images', 'images.tar', array('path' => $this->imagePath));
     }
     $xml->endElement();
     // append style info file to style tar
     $styleTar->addString(self::INFO_FILE, $xml->endDocument());
     unset($string);
     // create variable list
     $xml->beginDocument('variables', 'http://www.woltlab.com', 'http://www.woltlab.com/XSD/maelstrom/styleVariables.xsd');
     // get variables
     $sql = "SELECT\t\tvariable.variableName, value.variableValue\n\t\t\tFROM\t\twcf" . WCF_N . "_style_variable_value value\n\t\t\tLEFT JOIN\twcf" . WCF_N . "_style_variable variable\n\t\t\tON\t\t(variable.variableID = value.variableID)\n\t\t\tWHERE\t\tvalue.styleID = ?";
     $statement = WCF::getDB()->prepareStatement($sql);
     $statement->execute(array($this->styleID));
     while ($row = $statement->fetchArray()) {
         $xml->writeElement('variable', $row['variableValue'], array('name' => $row['variableName']));
     }
     // append variable list to style tar
     $styleTar->addString('variables.xml', $xml->endDocument());
     unset($string);
     if ($templates && $this->templateGroupID) {
         $templateGroup = new TemplateGroup($this->templateGroupID);
         // create templates tar
         $templatesTarName = FileUtil::getTemporaryFilename('templates', '.tar');
         $templatesTar = new TarWriter($templatesTarName);
         FileUtil::makeWritable($templatesTarName);
         // append templates to tar
         // get templates
         $sql = "SELECT\t\ttemplate.*, package.package\n\t\t\t\tFROM\t\twcf" . WCF_N . "_template template\n\t\t\t\tLEFT JOIN\twcf" . WCF_N . "_package package\n\t\t\t\tON\t\t(package.packageID = template.packageID)\n\t\t\t\tWHERE\t\ttemplate.templateGroupID = ?";
         $statement = WCF::getDB()->prepareStatement($sql);
         $statement->execute(array($this->templateGroupID));
         while ($row = $statement->fetchArray()) {
             $packageDir = 'com.woltlab.wcf';
             $package = null;
             if ($row['application'] != 'wcf') {
                 $application = ApplicationHandler::getInstance()->getApplication($row['application']);
                 $package = PackageCache::getInstance()->getPackage($application->packageID);
                 $packageDir = $package->package;
             } else {
                 $application = ApplicationHandler::getInstance()->getWCF();
                 $package = PackageCache::getInstance()->getPackage($application->packageID);
             }
             $filename = FileUtil::addTrailingSlash(FileUtil::getRealPath(WCF_DIR . $package->packageDir . 'templates/' . $templateGroup->templateGroupFolderName)) . $row['templateName'] . '.tpl';
             $templatesTar->add($filename, $packageDir, dirname($filename));
         }
         // append templates tar to style tar
         $templatesTar->create();
         $styleTar->add($templatesTarName, 'templates.tar', $templatesTarName);
         @unlink($templatesTarName);
     }
     if ($images && ($this->imagePath && $this->imagePath != 'images/')) {
         // create images tar
         $imagesTarName = FileUtil::getTemporaryFilename('images_', '.tar');
         $imagesTar = new TarWriter($imagesTarName);
         FileUtil::makeWritable($imagesTarName);
         // append images to tar
         $path = FileUtil::addTrailingSlash(WCF_DIR . $this->imagePath);
         if (file_exists($path) && is_dir($path)) {
             $handle = opendir($path);
             $regEx = new Regex('\\.(jpg|jpeg|gif|png|svg)$', Regex::CASE_INSENSITIVE);
             while (($file = readdir($handle)) !== false) {
                 if (is_file($path . $file) && $regEx->match($file)) {
                     $imagesTar->add($path . $file, '', $path);
                 }
             }
         }
         // append images tar to style tar
         $imagesTar->create();
         $styleTar->add($imagesTarName, 'images.tar', $imagesTarName);
         @unlink($imagesTarName);
     }
     // output file content
     $styleTar->create();
     // export as style package
     if (empty($packageName)) {
         readfile($styleTarName);
     } else {
         // export as package
         // create package tar
         $packageTarName = FileUtil::getTemporaryFilename('package_', '.tar.gz');
         $packageTar = new TarWriter($packageTarName, true);
         // append style tar
         $styleTarName = FileUtil::unifyDirSeparator($styleTarName);
         $packageTar->add($styleTarName, '', FileUtil::addTrailingSlash(dirname($styleTarName)));
         // create package.xml
         $xml->beginDocument('package', 'http://www.woltlab.com', 'http://www.woltlab.com/XSD/maelstrom/package.xsd', array('name' => $packageName));
         $xml->startElement('packageinformation');
         $xml->writeElement('packagename', $this->styleName);
         // description
         foreach ($styleDescriptions as $languageCode => $value) {
             $xml->writeElement('packagedescription', $value, array('language' => $languageCode));
         }
         $xml->writeElement('version', $this->styleVersion);
         $xml->writeElement('date', $this->styleDate);
         $xml->endElement();
         $xml->startElement('authorinformation');
         $xml->writeElement('author', $this->authorName);
         if ($this->authorURL) {
             $xml->writeElement('authorurl', $this->authorURL);
         }
         $xml->endElement();
         $xml->startElement('requiredpackages');
         $xml->writeElement('requiredpackage', 'com.woltlab.wcf', array('minversion' => PackageCache::getInstance()->getPackageByIdentifier('com.woltlab.wcf')->packageVersion));
         $xml->endElement();
         $xml->startElement('excludedpackages');
         $xml->writeElement('excludedpackage', 'com.woltlab.wcf', array('version' => self::EXCLUDE_WCF_VERSION));
         $xml->endElement();
         $xml->startElement('instructions', array('type' => 'install'));
         $xml->writeElement('instruction', basename($styleTarName), array('type' => 'style'));
         $xml->endElement();
         // append package info file to package tar
         $packageTar->addString(PackageArchive::INFO_FILE, $xml->endDocument());
         $packageTar->create();
         readfile($packageTarName);
         @unlink($packageTarName);
     }
     @unlink($styleTarName);
 }
Exemplo n.º 5
0
 /**
  * Write the languages files.
  * 
  * @param	array<integer>		$languageCategoryIDs
  */
 protected function writeLanguageFiles(array $languageCategoryIDs)
 {
     $conditions = new PreparedStatementConditionBuilder();
     $conditions->add("languageID = ?", array($this->languageID));
     $conditions->add("languageCategoryID IN (?)", array($languageCategoryIDs));
     // get language items
     $sql = "SELECT\tlanguageItem, languageItemValue, languageCustomItemValue,\n\t\t\t\tlanguageUseCustomValue, languageCategoryID\n\t\t\tFROM\twcf" . WCF_N . "_language_item\n\t\t\t" . $conditions;
     $statement = WCF::getDB()->prepareStatement($sql);
     $statement->execute($conditions->getParameters());
     $items = array();
     while ($row = $statement->fetchArray()) {
         $languageCategoryID = $row['languageCategoryID'];
         if (!isset($items[$languageCategoryID])) {
             $items[$languageCategoryID] = array();
         }
         $items[$languageCategoryID][$row['languageItem']] = $row['languageUseCustomValue'] ? $row['languageCustomItemValue'] : $row['languageItemValue'];
     }
     foreach ($items as $languageCategoryID => $languageItems) {
         $category = LanguageFactory::getInstance()->getCategoryByID($languageCategoryID);
         if ($category === null) {
             continue;
         }
         $filename = WCF_DIR . 'language/' . $this->languageID . '_' . $category->languageCategory . '.php';
         $writer = new AtomicWriter($filename);
         $writer->write("<?php\n/**\n* WoltLab Community Framework\n* language: " . $this->languageCode . "\n* encoding: UTF-8\n* category: " . $category->languageCategory . "\n* generated at " . gmdate("r") . "\n* \n* DO NOT EDIT THIS FILE\n*/\n");
         foreach ($languageItems as $languageItem => $languageItemValue) {
             $writer->write("\$this->items['" . $languageItem . "'] = '" . str_replace("'", "\\'", $languageItemValue) . "';\n");
             // compile dynamic language variables
             if ($category->languageCategory != 'wcf.global' && strpos($languageItemValue, '{') !== false) {
                 $writer->write("\$this->dynamicItems['" . $languageItem . "'] = '");
                 $output = LanguageFactory::getInstance()->getScriptingCompiler()->compileString($languageItem, $languageItemValue);
                 $writer->write(str_replace("'", "\\'", $output['template']));
                 $writer->write("';\n");
             }
         }
         $writer->flush();
         $writer->close();
         FileUtil::makeWritable($filename);
     }
 }
Exemplo n.º 6
0
 /**
  * Compiles LESS stylesheets into one CSS-stylesheet and writes them
  * to filesystem. Please be aware not to append '.css' within $filename!
  * 
  * @param	string			$filename
  * @param	array<string>		$files
  * @param	array<string>		$variables
  * @param	string			$individualLess
  * @param	\wcf\system\Callback	$callback
  */
 protected function compileStylesheet($filename, array $files, array $variables, $individualLess, Callback $callback)
 {
     foreach ($variables as &$value) {
         if (StringUtil::startsWith($value, '../')) {
             $value = '~"' . $value . '"';
         }
     }
     unset($value);
     // add options as LESS variables
     if (PACKAGE_ID) {
         foreach (Option::getOptions() as $constantName => $option) {
             if (in_array($option->optionType, static::$supportedOptionType)) {
                 $variables['wcf_option_' . mb_strtolower($constantName)] = '~"' . $option->optionValue . '"';
             }
         }
     } else {
         // workaround during setup
         $variables['wcf_option_attachment_thumbnail_height'] = '~"210"';
         $variables['wcf_option_attachment_thumbnail_width'] = '~"280"';
         $variables['wcf_option_signature_max_image_height'] = '~"150"';
     }
     // build LESS bootstrap
     $less = $this->bootstrap($variables);
     foreach ($files as $file) {
         $less .= $this->prepareFile($file);
     }
     // append individual CSS/LESS
     if ($individualLess) {
         $less .= $individualLess;
     }
     try {
         $content = $this->compiler->compile($less);
     } catch (\Exception $e) {
         throw new SystemException("Could not compile LESS: " . $e->getMessage(), 0, '', $e);
     }
     $content = $callback($content);
     // compress stylesheet
     $lines = explode("\n", $content);
     $content = $lines[0] . "\n" . $lines[1] . "\n";
     for ($i = 2, $length = count($lines); $i < $length; $i++) {
         $line = trim($lines[$i]);
         $content .= $line;
         switch (substr($line, -1)) {
             case ',':
                 $content .= ' ';
                 break;
             case '}':
                 $content .= "\n";
                 break;
         }
         if (substr($line, 0, 6) == '@media') {
             $content .= "\n";
         }
     }
     // write stylesheet
     file_put_contents($filename . '.css', $content);
     FileUtil::makeWritable($filename . '.css');
     // convert stylesheet to RTL
     $content = StyleUtil::convertCSSToRTL($content);
     // write stylesheet for RTL
     file_put_contents($filename . '-rtl.css', $content);
     FileUtil::makeWritable($filename . '-rtl.css');
 }
 /**
  * @see	\wcf\action\IAction::execute()
  */
 public function execute()
 {
     parent::execute();
     if ($this->user->enableGravatar) {
         $fileExtension = $this->user->gravatarFileExtension ?: 'png';
         // try to use cached gravatar
         $cachedFilename = sprintf(Gravatar::GRAVATAR_CACHE_LOCATION, md5(mb_strtolower($this->user->email)), $this->size, $fileExtension);
         if (file_exists(WCF_DIR . $cachedFilename) && filemtime(WCF_DIR . $cachedFilename) > TIME_NOW - Gravatar::GRAVATAR_CACHE_EXPIRE * 86400) {
             @header('Content-Type: image/png');
             @readfile(WCF_DIR . $cachedFilename);
             exit;
         }
         // try to download new version
         $gravatarURL = sprintf(Gravatar::GRAVATAR_BASE, md5(mb_strtolower($this->user->email)), $this->size, GRAVATAR_DEFAULT_TYPE);
         try {
             $request = new HTTPRequest($gravatarURL);
             $request->execute();
             $reply = $request->getReply();
             // get mime type and file extension
             $fileExtension = 'png';
             $mimeType = 'image/png';
             if (isset($reply['headers']['Content-Type'])) {
                 switch ($reply['headers']['Content-Type']) {
                     case 'image/jpeg':
                         $mimeType = 'image/jpeg';
                         $fileExtension = 'jpg';
                         break;
                     case 'image/gif':
                         $mimeType = 'image/gif';
                         $fileExtension = 'gif';
                         break;
                 }
             }
             // save file
             $cachedFilename = sprintf(Gravatar::GRAVATAR_CACHE_LOCATION, md5(mb_strtolower($this->user->email)), $this->size, $fileExtension);
             file_put_contents(WCF_DIR . $cachedFilename, $reply['body']);
             FileUtil::makeWritable(WCF_DIR . $cachedFilename);
             // update file extension
             if ($fileExtension != $this->user->gravatarFileExtension) {
                 $editor = new UserEditor($this->user);
                 $editor->update(array('gravatarFileExtension' => $fileExtension));
             }
             @header('Content-Type: ' . $mimeType);
             @readfile(WCF_DIR . $cachedFilename);
             exit;
         } catch (SystemException $e) {
             // disable gravatar
             $editor = new UserEditor($this->user);
             $editor->update(array('enableGravatar' => 0));
         }
     }
     // fallback to default avatar
     @header('Content-Type: image/svg+xml');
     @readfile(WCF_DIR . 'images/avatars/avatar-default.svg');
     exit;
 }
Exemplo n.º 8
0
 /**
  * Makes a file or directory writeable.
  * 
  * @param	string		$target
  */
 protected function makeWriteable($target)
 {
     FileUtil::makeWritable($target);
 }
Exemplo n.º 9
0
 /**
  * Compiles LESS stylesheets.
  * 
  * @param	\cms\data\stylesheet\Stylesheet		$stylesheet
  * @param	integer					$styleID
  */
 public function compile(Stylesheet $stylesheet, $styleID = null)
 {
     $styles = StyleHandler::getInstance()->getStyles();
     // compile stylesheet for all installed styles
     if ($styleID === null) {
         foreach ($styles as $style) {
             $this->compile($stylesheet, $style->styleID);
         }
         return;
     }
     $style = $styles[$styleID];
     // get style variables
     $variables = $style->getVariables();
     if (isset($variables['individualLess'])) {
         unset($variables['individualLess']);
     }
     // add style image path
     $imagePath = '../images/';
     if ($style->imagePath) {
         $imagePath = FileUtil::getRelativePath(WCF_DIR . 'style/', WCF_DIR . $style->imagePath);
         $imagePath = FileUtil::addTrailingSlash(FileUtil::unifyDirSeparator($imagePath));
     }
     $variables['style_image_path'] = "'{$imagePath}'";
     // apply overrides
     if (isset($variables['overrideLess'])) {
         $lines = explode("\n", StringUtil::unifyNewlines($variables['overrideLess']));
         foreach ($lines as $line) {
             if (preg_match('~^@([a-zA-Z]+): ?([@a-zA-Z0-9 ,\\.\\(\\)\\%\\#-]+);$~', $line, $matches)) {
                 $variables[$matches[1]] = $matches[2];
             }
         }
         unset($variables['overrideLess']);
     }
     // add options as LESS variables
     foreach (Option::getOptions() as $constantName => $option) {
         if (in_array($option->optionType, array('boolean', 'integer'))) {
             $variables['wcf_option_' . mb_strtolower($constantName)] = '~"' . $option->optionValue . '"';
         }
     }
     // compile
     $this->compiler->setVariables($variables);
     $content = "/* stylesheet for '" . $stylesheet->getTitle() . "', generated on " . gmdate('r') . " -- DO NOT EDIT */\n\n";
     $content .= $this->compiler->compile($stylesheet->less);
     // compress stylesheet
     $lines = explode("\n", $content);
     $content = $lines[0] . "\n" . $lines[1] . "\n";
     for ($i = 2, $length = count($lines); $i < $length; $i++) {
         $line = trim($lines[$i]);
         $content .= $line;
         switch (substr($line, -1)) {
             case ',':
                 $content .= ' ';
                 break;
             case '}':
                 $content .= "\n";
                 break;
         }
         if (substr($line, 0, 6) == '@media') {
             $content .= "\n";
         }
     }
     // write stylesheet
     $filename = $stylesheet->getLocation($styleID);
     file_put_contents($filename, $content);
     FileUtil::makeWritable($filename);
     // write rtl stylesheet
     $content = StyleUtil::convertCSSToRTL($content);
     $filename = $stylesheet->getLocation($styleID, true);
     file_put_contents($filename, $content);
     FileUtil::makeWritable($filename);
 }
 /**
  * Prompts for a text input for package directory (applies for applications only)
  * 
  * @return	\wcf\system\form\FormDocument
  */
 protected function promptPackageDir()
 {
     if (!PackageInstallationFormManager::findForm($this->queue, 'packageDir')) {
         $container = new GroupFormElementContainer();
         $packageDir = new TextInputFormElement($container);
         $packageDir->setName('packageDir');
         $packageDir->setLabel(WCF::getLanguage()->get('wcf.acp.package.packageDir.input'));
         $defaultPath = FileUtil::addTrailingSlash(FileUtil::unifyDirSeparator(dirname(WCF_DIR)));
         // check if there is already an application
         $sql = "SELECT\tCOUNT(*) AS count\n\t\t\t\tFROM\twcf" . WCF_N . "_package\n\t\t\t\tWHERE\tpackageDir = ?";
         $statement = WCF::getDB()->prepareStatement($sql);
         $statement->execute(array('../'));
         $row = $statement->fetchArray();
         if ($row['count']) {
             // use abbreviation
             $defaultPath .= strtolower(Package::getAbbreviation($this->getPackage()->package)) . '/';
         }
         $packageDir->setValue($defaultPath);
         $container->appendChild($packageDir);
         $document = new FormDocument('packageDir');
         $document->appendContainer($container);
         PackageInstallationFormManager::registerForm($this->queue, $document);
         return $document;
     } else {
         $document = PackageInstallationFormManager::getForm($this->queue, 'packageDir');
         $document->handleRequest();
         $packageDir = FileUtil::addTrailingSlash(FileUtil::getRealPath(FileUtil::unifyDirSeparator($document->getValue('packageDir'))));
         if ($packageDir === '/') {
             $packageDir = '';
         }
         if ($packageDir !== null) {
             // validate package dir
             if (file_exists($packageDir . 'global.php')) {
                 $document->setError('packageDir', WCF::getLanguage()->get('wcf.acp.package.packageDir.notAvailable'));
                 return $document;
             }
             // set package dir
             $packageEditor = new PackageEditor($this->getPackage());
             $packageEditor->update(array('packageDir' => FileUtil::getRelativePath(WCF_DIR, $packageDir)));
             // determine domain path, in some environments (e.g. ISPConfig) the $_SERVER paths are
             // faked and differ from the real filesystem path
             if (PACKAGE_ID) {
                 $wcfDomainPath = ApplicationHandler::getInstance()->getWCF()->domainPath;
             } else {
                 $sql = "SELECT\tdomainPath\n\t\t\t\t\t\tFROM\twcf" . WCF_N . "_application\n\t\t\t\t\t\tWHERE\tpackageID = ?";
                 $statement = WCF::getDB()->prepareStatement($sql);
                 $statement->execute(array(1));
                 $row = $statement->fetchArray();
                 $wcfDomainPath = $row['domainPath'];
             }
             $documentRoot = str_replace($wcfDomainPath, '', FileUtil::unifyDirSeparator(WCF_DIR));
             $domainPath = str_replace($documentRoot, '', $packageDir);
             // update application path
             $application = new Application($this->getPackage()->packageID);
             $applicationEditor = new ApplicationEditor($application);
             $applicationEditor->update(array('domainPath' => $domainPath, 'cookiePath' => $domainPath));
             // create directory and set permissions
             @mkdir($packageDir, 0777, true);
             FileUtil::makeWritable($packageDir);
         }
         return null;
     }
 }
Exemplo n.º 11
0
 /**
  * @see	\wcf\system\io\IArchive::extract()
  */
 public function extract($offset, $destination)
 {
     if (!is_int($offset)) {
         $offset = $this->getIndexByFilename($offset);
     }
     try {
         $file = $this->readFile($offset);
     } catch (SystemException $e) {
         return false;
     }
     FileUtil::makePath(dirname($destination));
     if ($file['header']['type'] === 'folder') {
         FileUtil::makePath($destination);
         return;
     }
     $targetFile = new File($destination);
     $targetFile->write($file['content'], strlen($file['content']));
     $targetFile->close();
     FileUtil::makeWritable($destination);
     if ($file['header']['mtime']) {
         @$targetFile->touch($file['header']['mtime']);
     }
     // check filesize
     if (filesize($destination) != $file['header']['size']) {
         throw new SystemException("Could not unzip file '" . $file['header']['filename'] . "' to '" . $destination . "'. Maybe disk quota exceeded in folder '" . dirname($destination) . "'.");
     }
     return true;
 }