2 /***********************************************************************/
4 /***********************************************************************/
5 /* Copyright (c) 2002-2010 */
6 /* Inclusive Design Institute */
9 /* This program is free software. You can redistribute it and/or */
10 /* modify it under the terms of the GNU General Public License */
11 /* as published by the Free Software Foundation. */
12 /***********************************************************************/
15 define('PCLZIP_TEMPORARY_DIR', AT_CONTENT_DIR.'export'.DIRECTORY_SEPARATOR); //constant for the temp folder.
16 include(AT_INCLUDE_PATH.'classes/pclzip.lib.php'); //loads the pclzip library.
17 include_once(AT_INCLUDE_PATH.'../mods/_core/file_manager/filemanager.inc.php'); //copy/delete folder
20 * Class for creating and accessing an archive zip file. Originally written by Joel Kronenberg,
21 * edited by Harris Wong to use the PCLZIP library (http://www.phpconcept.net)
23 * As of ATutor 2.0, this file will extend the pclzip library functions instead of using Joel's.
24 * The function preconditions and postconditions will remain the same however.
27 * @link http://www.pkware.com/documents/casestudies/APPNOTE.TXT for the specs
28 * @author Joel Kronenberg
33 * string $zipfile_dir - the actual system directory that stores the temporary files for archiving.
39 * boolean $is_closed - flag set to true if file is closed, false if still open
45 * string $filename - randomized filename of this zip instance. It also shares the same name
46 * as the folder under the export/ folder.
52 * Constructor method. Initialises variables.
54 * @author Joel Kronenberg
57 //create the temp folder for export if it hasn't been created.
58 if (!is_dir(PCLZIP_TEMPORARY_DIR)){
59 mkdir(PCLZIP_TEMPORARY_DIR);
60 copy(PCLZIP_TEMPORARY_DIR.'../index.html', PCLZIP_TEMPORARY_DIR.'index.html');
63 //generate a random hash
64 $this->filename = substr(md5(rand()), 0, 5);
66 //create a temporary folder for this zip instance
67 $this->zipfile_dir = PCLZIP_TEMPORARY_DIR.$this->filename.DIRECTORY_SEPARATOR;
68 mkdir($this->zipfile_dir);
69 $this->is_closed = false;
74 * Public interface for adding a dir and its contents recursively to zip file
76 * @param string $dir the real system directory that contains the files to add to the zip
77 * @param string $zip_prefix_dir the zip dir where the contents of $dir will be put in
78 * @param string $pre_pend_dir used during the recursion to keep track of the path, default=''
79 * @see $_base_path in include/vitals.inc.php
80 * @see priv_add_dir() in include/classes/zipfile.class.php
81 * @see add_file() in include/classes/zipfile.class.php
82 * @author Joel Kronenberg
84 function add_dir($dir, $zip_prefix_dir, $pre_pend_dir='') {
85 if (!($dh = @opendir($dir.$pre_pend_dir))) {
86 echo 'cant open dir: '.$dir.$pre_pend_dir;
89 //copy folder recursively into the temp folder.
90 copys($dir, $this->zipfile_dir.DIRECTORY_SEPARATOR.$zip_prefix_dir);
94 * Adding a dir to the archive
96 * @param string $name directory name
97 * @param string $timestamp time, default=''
98 * @author Joel Kronenberg
100 function priv_add_dir($name, $timestamp = '') {
101 //deprecated as of ATutor 2.0
105 * Public interface to create a directory in the archive.
107 * @param string $name directory name
108 * @param string $timestamp time of creation, default=''
109 * @see $_base_path in include/vitals.inc.php
110 * @see priv_add_dir() in include/zipfile.class.php
111 * @author Joel Kronenberg
113 function create_dir($name, $timestamp='') {
115 //don't create a folder if it is itself
116 if ($name=='' || $name=='.'){
120 $parent_folder = dirname($name);
121 if (!is_dir($this->zipfile_dir.$name) && ($parent_folder=='.' || $parent_folder=='')){
123 mkdir($this->zipfile_dir.$name);
127 $this->create_dir(dirname($name));
130 //returned stack. continue from where it left off.
131 if (!is_dir($this->zipfile_dir.$name)){
132 //the parent folder should be created at this point, create itself
133 mkdir($this->zipfile_dir.$name);
139 * Adds a file to the archive.
141 * @param string $file_data file contents
142 * @param string $name name of file in archive (add path if your want)
143 * @param string $timestamp time of creation, default=''
144 * @see $_base_path in include/vitals.inc.php
145 * @see priv_add_dir() in include/zipfile.class.php
146 * @author Joel Kronenberg
148 function add_file($file_data, $name, $timestamp = '') {
149 $name = str_replace("\\", "/", $name);
151 //check if folder exists, if not, create it.
152 if (!is_dir($this->zipfile_dir.dirname($name))){
153 $this->create_dir(dirname($name));
157 $fp = fopen($this->zipfile_dir.$name, 'w');
158 fwrite($fp, $file_data);
163 * Closes archive, sets $is_closed to true
166 * @author Joel Kronenberg
169 //use pclzip to compress the file, and save it in the temp folder.
170 $archive = new PclZip($this->zipfile_dir.$this->filename.'.zip');
171 $v_list = $archive->create($this->zipfile_dir,
172 PCLZIP_OPT_REMOVE_PATH, $this->zipfile_dir);
176 die ("Error: " . $archive->errorInfo(true));
179 $this->is_closed = true;
183 * Gets size of new archive
184 * Only call this after calling close() - will return false if the zip wasn't close()d yet
186 * @return int size of file in byte.
187 * @author Joel Kronenberg
189 function get_size() {
190 if (!$this->is_closed) {
195 $filepath = $this->zipfile_dir.$this->filename.'.zip';
196 if (file_exists($filepath)){
197 return filesize($filepath);
205 * Returns binary file
207 * @see get_size() in include/classes/zipfile.class.php
208 * @author Joel Kronenberg
210 function get_file() {
211 if (!$this->is_closed) {
214 return file_get_contents($this->zipfile_dir.$this->filename.'.zip');
218 * Writes the file to disk.
219 * Similar to get_file(), but instead of returning the file, it saves it to disk.
221 * @author Joel Kronenberg
222 * @param $file The full path and file name of the destination file.
224 function write_file($file) {
225 if (!$this->is_closed) {
228 copy($this->zipfile_dir.$this->filename.'.zip', $file);
233 * Outputs the file - sends headers to browser to force download
234 * Only call this after calling close() - will return false if the zip wasn't close()d yet
236 * @see get_size() in include/classes/zipfile.class.php
237 * @author Joel Kronenberg
239 function send_file($file_name) {
240 if (!$this->is_closed) {
243 $file_name = str_replace(array('"', '<', '>', '|', '?', '*', ':', '/', '\\'), '', $file_name);
245 header("Content-type: archive/zip");
246 header("Content-disposition: attachment; filename=$file_name.zip");
248 readfile_in_chunks($this->zipfile_dir.$this->filename.'.zip');
253 * Destructor - removes temporary folder and its content.
254 * Should self-destruct automatically for PHP 5.0+; otherwise developers should call this function
257 * @author Harris Wong
259 function __destruct(){
260 clr_dir($this->zipfile_dir);