function copyOrRename($src, $dest, $rename)
{
    if (file_exists($src)) {
        if ($rename) {
            FilesHelper::renameFile($src, $dest);
        } else {
            FilesHelper::copyRecursive($src, $dest);
        }
    }
}
 /**
  * Saves designer project to current theme
  */
 public function save($info)
 {
     $chunk = new Chunk();
     if (!$chunk->save($info)) {
         header($_SERVER['SERVER_PROTOCOL'] . ' 400 Bad Request', true, 400);
         return array();
     }
     if ($chunk->last()) {
         ProviderLog::start('save');
         ProviderLog::start('save:json decode');
         // merge and decode content
         $result = json_decode($chunk->complete(), true);
         ProviderLog::end('save:json decode');
         $thumbnails = array_key_exists('thumbnails', $result) > 0 ? $result['thumbnails'] : '';
         $cssJsSources = array_key_exists('cssJsSources', $result) > 0 ? $result['cssJsSources'] : '';
         $md5Hashes = array_key_exists('md5Hashes', $result) > 0 ? $result['md5Hashes'] : '';
         $projectData = array_key_exists('projectData', $result) > 0 ? $result['projectData'] : '';
         $images = empty($result['images']) ? null : $result['images'];
         $helper = new PreviewHelper($this->_themeDir);
         $changed_files = getPreviewChangedFiles($this->_themeDir);
         FilesHelper::deleteFile($this->_themeDir . '/css/global.min.css');
         FilesHelper::deleteFile($this->_themeDir . '/css/bootstrap.min.css');
         ProviderLog::start('Save files');
         foreach ($changed_files as $file) {
             if (has_version_in_path($file)) {
                 continue;
             }
             $path = $this->_previewThemeDir . $file;
             $themeFileDir = dirname($path);
             if (file_exists($path)) {
                 if (strpos($file, 'designer/') || strpos($file, 'designerpreview/') || strpos($file, 'blocktopmenu_mod/')) {
                     FilesHelper::copyRecursive($path, $this->_modulesDir . $file);
                 } else {
                     if (preg_match('#[\\\\/]img$#', $themeFileDir)) {
                         // file inside 'img' directory
                         FilesHelper::renameFile($path, $this->_themeDir . $file);
                     } else {
                         FilesHelper::copyRecursive($path, $this->_themeDir . $file, array($helper, "removeDataId"));
                     }
                 }
             } else {
                 $helper->removeKey($file);
                 FilesHelper::deleteFile($this->_themeDir . $file);
             }
         }
         ProviderLog::end('Save files');
         ProviderLog::start('Save images');
         $this->_processImages($this->_themeDir, $images, $changed_files);
         ProviderLog::end('Save images');
         ProviderLog::start('_fixPreviewImagePaths');
         $this->_fixPreviewImagePaths();
         ProviderLog::end('_fixPreviewImagePaths');
         ProviderLog::start('Update module files');
         // backward fix with module override files
         FilesHelper::copyRecursive($this->_modulesDir . '/designerpreview/override', FilesHelper::normalizePath(_PS_OVERRIDE_DIR_));
         FilesHelper::copyRecursive($this->_modulesDir . '/designer/override', FilesHelper::normalizePath(_PS_OVERRIDE_DIR_));
         ProviderLog::end('Update module files');
         setPreviewChangedFiles($this->_themeDir, $this->_previewThemeDir, array());
         $helper->save();
         $this->_saveThumbnails($thumbnails);
         if (!empty($projectData)) {
             saveProject($this->_themeName, $projectData);
         }
         if (!empty($cssJsSources)) {
             setThemeCache($this->_themeDir, $cssJsSources);
         }
         if (!empty($md5Hashes)) {
             setThemeHashes($this->_themeDir, $md5Hashes);
         }
         ProviderLog::start('updateTranslations');
         updateTranslations($this->_themeDir);
         ProviderLog::end('updateTranslations');
         ProviderLog::end('save');
         return array('result' => 'done', 'log' => ProviderLog::getLog());
     }
     return array('result' => 'processed');
 }