public function save($info)
 {
     $validationResult = $this->validate($info);
     if ('' !== $validationResult) {
         trigger_error($validationResult, E_USER_ERROR);
     }
     $this->_lastChunk = $info;
     $this->_chunkFolder = $this->UPLOAD_PATH . $info['id'];
     $this->_lockFile = $this->_chunkFolder . '/lock';
     FilesHelper::createDir($this->_chunkFolder);
     $f = fopen($this->_lockFile, 'c');
     if (flock($f, LOCK_EX)) {
         $chunks = array_diff(scandir($this->_chunkFolder), array('.', '..', 'lock'));
         if ((int) $this->_lastChunk['total'] === count($chunks) + 1) {
             $this->_isLast = true;
         }
         if (!empty($this->_lastChunk['blob'])) {
             if (empty($_FILES['content']['tmp_name'])) {
                 ProviderLog::end('Chunk save');
                 return false;
             }
             $content = file_get_contents($_FILES['content']['tmp_name']);
             unlink($_FILES['content']['tmp_name']);
         } else {
             $content = $info['content'];
         }
         FilesHelper::writeFile($this->_chunkFolder . '/' . (int) $info['current'], $content);
         flock($f, LOCK_UN);
         ProviderLog::end('Chunk save');
         return true;
     } else {
         trigger_error('Couldn\'t lock the file: ' . $this->_lockFile, E_USER_NOTICE);
     }
 }
function add_version_folders(&$archive, $base_upload_dir, $user_template_dir, $preview_template_folder, $userThemeName, $includeThemler)
{
    $preview_files = array();
    foreach (get_support_versions() as $version) {
        $preview_files[$version] = FilesHelper::enumerateFiles($preview_template_folder . '/' . $version);
    }
    $preview_name = $userThemeName . _PREVIEW_SUFFIX_;
    $version_folders = get_support_versions_folder($user_template_dir);
    $cms_version = get_cms_version();
    $dirs = array('themes', 'modules');
    $modules = array('designerpreview', 'blocktopmenu_mod');
    if ($includeThemler) {
        $modules[] = 'designer';
    }
    foreach ($version_folders as $version => $folder) {
        $root = $base_upload_dir . (strpos($cms_version, $version) !== false ? '' : '/' . $version);
        foreach ($dirs as $name) {
            $dir = $root . '/' . $name;
            $arch_dirs[$name] = $dir;
            FilesHelper::createDir($dir);
        }
        FilesHelper::copyRecursive($user_template_dir, $arch_dirs['themes'] . '/' . $userThemeName);
        foreach ($modules as $module) {
            FilesHelper::copyRecursive(_PS_MODULE_DIR_ . $module, $arch_dirs['modules'] . '/' . $module);
        }
        // current version files in preview folder doesn't need to be copied
        if (strpos($cms_version, $version) !== false) {
            continue;
        }
        $files = $preview_files[$version];
        $pattern = '/(.*?\\/themes\\/' . $preview_name . '\\/' . $version . '\\/)(.*?)/si';
        foreach ($files as $file) {
            $path = $file['path'];
            $isThemler = strpos($path, 'designer/');
            if ($isThemler && !$includeThemler) {
                continue;
            }
            $isModule = $isThemler || strpos($path, 'designerpreview/') || strpos($path, 'blocktopmenu_mod/');
            $to_replace = ($isModule ? $arch_dirs['modules'] : $arch_dirs['themes'] . '/' . $userThemeName) . '/$2';
            $r_path = preg_replace($pattern, $to_replace, $path);
            $r_path = FilesHelper::normalizePath($r_path);
            FilesHelper::writeFile($r_path, $file['content']);
        }
        // add version folder as root folder to archive file
        addToArchive($archive, $root, $base_upload_dir);
        FilesHelper::removeDir($root, true);
    }
    if ($includeThemler) {
        $inner_preview_dir = $base_upload_dir . '/themes/' . $userThemeName . '/' . $userThemeName . _PREVIEW_SUFFIX_;
        FilesHelper::copyRecursive($preview_template_folder, $inner_preview_dir);
    }
    foreach ($dirs as $dir) {
        addToArchive($archive, $base_upload_dir . '/' . $dir, $base_upload_dir);
    }
    clearDirs($base_upload_dir, $dirs);
    return;
}
function uploadTheme($themeName, $filename, $tmp_path)
{
    $uniqid = uniqid();
    $sandbox = FilesHelper::normalizePath(_PS_CACHE_DIR_ . 'sandbox' . DIRECTORY_SEPARATOR . $uniqid) . '/';
    $uploadDir = $sandbox . ThemeInstallHelper::UPLOADED_THEME_DIR_NAME;
    // used in AdminThemesController
    $base_path = $uploadDir . '.zip';
    FilesHelper::createDir($sandbox);
    FilesHelper::renameFile($tmp_path, $base_path);
    $archive = new PclZip($base_path);
    deleteFromArchive($archive, 'modules', true);
    // We upload new theme, not modules to save module functionality
    $helper = new ThemeInstallHelper();
    if ($helper->install($base_path, $sandbox)) {
        $result = array('status' => 'done', 'path' => $base_path);
    } else {
        $themesDir = $uploadDir . '/themes';
        $files = FilesHelper::enumerate($themesDir, false);
        // not enumerateFiles method with directory checking
        if (count($files) === 1 && is_dir($files[0]['path'])) {
            $themeName = str_replace("{$themesDir}/", '', $files[0]['path']);
        }
        if ($themeName && ($theme = Theme::getByDirectory($themeName)) && is_file($uploadDir . '/Config.xml')) {
            $themeDir = $themesDir . '/' . $themeName;
            $previewThemeDir = $themeDir . '/' . $themeName . _PREVIEW_SUFFIX_;
            $newThemeName = checkThemeName($themeName);
            $newThemeDir = $themesDir . '/' . $newThemeName;
            $newThemePreviewDir = $themeDir . '/' . $newThemeName . _PREVIEW_SUFFIX_;
            // 1. rename inner preview folder
            processRename($themeDir, $previewThemeDir, $newThemeDir, $newThemePreviewDir, $newThemeName);
            $newThemePreviewDir = $newThemeDir . '/' . $newThemeName . _PREVIEW_SUFFIX_;
            // 2. now preview folder is correct
            FilesHelper::deleteFile($uploadDir . '/Config.xml');
            FilesHelper::copyFile($newThemePreviewDir . '/designer/Export/Config.xml', $uploadDir . '/Config.xml');
            unset($archive);
            FilesHelper::deleteFile($base_path);
            $archive = new PclZip($base_path);
            addToArchive($archive, $uploadDir, $uploadDir);
            $helper = new ThemeInstallHelper();
            // new object with no errors
            if ($helper->install($base_path, $sandbox)) {
                $result = array('status' => 'done', 'path' => $base_path);
            } else {
                $result = array('status' => 'error', 'errors' => Tools::jsonEncode($helper->getErrors()));
            }
        } else {
            $result = array('status' => 'error', 'errors' => 'Please make sure, that you have selected a valid PrestaShop theme.');
        }
    }
    return $result;
}
 private function _processFile($root, $inner_folder_path, $file_name, $content, &$changed_files, &$replaceInfo, $hasReplace)
 {
     // correct inner path to folder without version
     $folders = correct_version_path($inner_folder_path);
     foreach ($folders as $folder) {
         $path = FilesHelper::normalizePath($root . '/' . $folder);
         FilesHelper::createDir($path);
         $path .= '/' . $file_name;
         $info = pathinfo($path);
         $fileName = $info['basename'];
         $fileExt = isset($info['extension']) && $info['extension'] ? $info['extension'] : '';
         $isTemplateFile = preg_match('#[\\\\/]' . $this->_previewThemeName . '[\\\\/](.*?)templates[\\\\/]#', $path, $m);
         if ($content === '[DELETED]') {
             FilesHelper::deleteFile($path);
         } elseif (in_array($fileExt, array('js')) && !strpos($path, 'designer/')) {
             $path = strpos($path, '/js/') || strpos($path, 'CloudZoom.js') ? $path : $root . '/js/' . $fileName;
             FilesHelper::writeFile($path, $content);
         } elseif (in_array($fileExt, array('css')) && !strpos($path, 'designer/')) {
             if ($fileName === 'style.css') {
                 $fileName = 'global.css';
             }
             $path = strpos($path, '/css/') ? $path : $root . '/css/' . $fileName;
             if ($hasReplace) {
                 $content = str_replace($replaceInfo['ids'], $replaceInfo['paths'], $content);
             }
             FilesHelper::writeFile($path, $content);
         } elseif (in_array($fileExt, array('tpl'))) {
             $result = $this->_replaceImageIdToUrl($content, $replaceInfo, $hasReplace);
             FilesHelper::writeFile($path, $result);
         } else {
             FilesHelper::writeFile($path, $content);
         }
         $changed_files[] = $path;
         // save changed file - source or modified
     }
 }