<?php
/*
Officity - Web application platform - Version 6.0 - 2011-07-05

François Dispaux, Boris Verdeyen, Thomas Hermant,
Jérémie Roy, Grégory Meurice, Abdelila Harbi, 
Marc Mignonsin, Jonathan Sanchez, Julien Gonzalez, Pierre Fouchez

Sushee and Officity is © Copyright 2011 Nectil SA.

`/sushee-source/sushee/private/createArchive.inc.php` is part of Officity.

Sushee is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

Officity and Sushee are distributed in the hope that they will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with Sushee. If not, see <http://www.gnu.org/licenses/>.
*/
require_once(dirname(__FILE__).'/../common/nqlOperation.class.php');
require_once(dirname(__FILE__).'/../common/file.class.php');
require_once(dirname(__FILE__).'/../common/nql.class.php');

class createArchive extends RetrieveOperation{
	
	var $includeFiles = true;
	var $sourceFolder = false;
	var $languageID = false;
	var $queryNode = false;
	
	function parse(){
		if(isset($GLOBALS['residentPublished']) && $GLOBALS['residentPublished']==0){
			$this->setError('Your resident is not published, therefore export is disabled.');
			return false;
		}
		
		$this->queryNode = $this->firstNode->getElement('QUERY');
		
		
		$sourceFolderPath = $this->firstNode->valueOf('@source-folder');
		if($sourceFolderPath){
			$this->sourceFolder = new KernelFile($sourceFolderPath);
			if(!$this->sourceFolder->exsist())
				$this->sourceFolder = false;
		}
		
		$languageID = $this->firstNode->valueOf('@languageID');
		if($languageID=='all')
			$languageID = false;
		$this->languageID = $languageID;
		
		
		$includeFiles = $this->firstNode->valueOf('@include-files');
		if($includeFiles==='false')
			$includeFiles = false;
		else
			$includeFiles = true;
		$this->includeFiles = $includeFiles;
			
		
		return true;
	}
	
	function operate(){
		$tmpDir = new TempDirectory();
		$tmpDir->create();
		if($this->sourceFolder){
			$rootDir = $tmpDir->createDirectory($this->sourceFolder->getName());
			$dataDir = $rootDir->createDirectory('data');
			$zipDir = $rootDir;
		}else{
			$rootDir = &$tmpDir;
			$dataDir = $rootDir->createDirectory('data');
			$zipDir = &$dataDir;
		}
		
		if($this->includeFiles){
			$filesDir = $dataDir->createDirectory('Files');
		}
		$nql = new NQL(false);
		$nql->includeSuppParams(false);
		$nql->addCommand(
			'<GET>
				<LANGUAGES profile="Media"/>
			</GET>');
		$nql->execute();
		
		if($this->languageID){
			$lgStr = '<?xml version="1.0" encoding="utf-8"?><RESPONSE><RESULTS>'.$nql->copyOf("/RESPONSE/RESULTS/LANGUAGE[@ID='".$this->languageID."']").'</RESULTS></RESPONSE>';
			$lgNodes = $nql->getElements("/RESPONSE/RESULTS/LANGUAGE[@ID='".$this->languageID."']");
		}else{
			$lgStr = $nql->getResponse();
			$lgNodes = $nql->getElements("/RESPONSE/RESULTS/LANGUAGE");
		}
		$lgFile = $dataDir->createFile('languages.xml');
		$lgFile->save($lgStr);
		
		$nql->reset();
		if($this->queryNode){
			if($this->includeFiles){
				$used_files = array();
				$GLOBALS['used_Files']=array();
			}
			foreach($lgNodes as $lgNode){
				$lgID = $lgNode->valueOf('@ID');

				$nql->setLanguage($lgID);
				$nql->addCommands(
					$this->queryNode->getElements('./*')
					);
				$nql->execute();

				$dataFile = $dataDir->createFile('data_'.$lgID.'.xml');
				$queryResponse = $nql->getResponse();
				$dataFile->save($queryResponse);
				$nql->reset();
				if($this->includeFiles){
					$used_files=array_merge($used_files,$GLOBALS['used_Files']);
				}
			}
		}
		if($this->includeFiles){
			// copying all files in the archive directory
			$skipped_files = array();
			$this->copy_published_content(getFilesRoot(),$filesDir->getCompletePath(),$used_files,$skipped_files);
			if(sizeof($skipped_files)>0){
				$html = '<html><body><h1>Missing files (too large to be zipped) : download them separately</h1><ul>';
				foreach($skipped_files as $short_path){
					$html.='<li><a href="'.$GLOBALS["backoffice_url"].'file/file_download.php?target='.$short_path.'">'.BaseFilename($short_path).'</a> to download separately in directory <strong>data/Files'.getShortPath(dirname($directoryRoot.$short_path)).'</strong></li>';
				}
				$html.= '</ul></body></html>';
				$missingTextFile = $dataDir->createFile('missing_files.html');
				$missingTextFile->save($html);
			}
		}
		$libMediaCSSFileOrig = new KernelFile('/Library/media/css/default.css');
		if ($libMediaCSSFileOrig->exists()){
			$libDir = $dataDir->createDirectory('Library');
			$libMediaDir = $libDir->createDirectory('media');
			$libMediaCssDir = $libMediaDir->createDirectory('css');
			$libMediaCssFileCopy = $libMediaCssDir->createFile('default.css');
			$libMediaCSSFileOrig->copy($libMediaCssFileCopy);
		}
			
		if ($this->sourceFolder && $this->sourceFolder->exists()){
			copy_content($this->sourceFolder->getCompletePath(),$rootDir->getCompletePath());
		}
			
		
		$zipFile = $zipDir->compress();
		if(!$zipFile){
			$this->setError('Problem with the compression of the package');
			return false;
		}
		$zipDir->delete();
		$xml = '';
		$attributes = $this->getOperationAttributes();
		$xml.='<RESULTS'.$attributes.'>';
		$xml.= 		'<ARCHIVE'.((sizeof($skipped_files)>0)?' missing_files="true"':'').'>'.$zipFile->getPath().'</ARCHIVE>';
		$xml.='</RESULTS>';
		$this->setXML($xml);
		return true;
	}
	
	function copy_published_content($source_dir,$target_dir,&$published_files,&$skipped_files){
		$source_dir = realpath($source_dir)."/";
		$target_dir = realpath($target_dir)."/";
		if (!file_exists($source_dir) || !file_exists($target_dir))
			return FALSE;
		if ($dir = @opendir($source_dir)) {
			$short_dir_path = getShortPath($source_dir);
			while($file = readdir($dir)) {
				$isFileVisible = true;
				if($file == "." || $file == ".." )
					$isFileVisible = false;
				if ($isFileVisible){
					if (is_dir($source_dir.$file)){
						$copy = false;
						// checking at least one of the published files is in the dir
						$short_dir = getShortPath($source_dir.$file);
						$short_dir_sz = strlen($short_dir);
						foreach($published_files as $pub_file){
							if ($short_dir==substr($pub_file,0,$short_dir_sz)){
								$copy=true;
								break;
							}
						}
						if ($copy){
							makeDir($target_dir.$file);
							$this->copy_published_content($source_dir.$file,$target_dir.$file,$published_files,$skipped_files);
						}
					}else{
						$short_path = getShortPath($source_dir.$file);
						if ( in_array ($short_path, $published_files) || in_array ($short_dir_path, $published_files)){
							if(filesize($source_dir.$file)>10240000)
								$skipped_files[]=$short_path;
							else
								copy($source_dir.$file,$target_dir.$file);
						}
					}
				}
			}
		}else
			return FALSE;
	}
}

?>
