2 exit('not yet complete');
\r
3 /****************************************************************/
\r
5 /****************************************************************/
\r
6 /* Copyright (c) 2002-2006 by Greg Gay & Joel Kronenberg */
\r
7 /* Adaptive Technology Resource Centre / University of Toronto */
\r
8 /* http://atutor.ca */
\r
10 /* This program is free software. You can redistribute it and/or*/
\r
11 /* modify it under the terms of the GNU General Public License */
\r
12 /* as published by the Free Software Foundation. */
\r
13 /****************************************************************/
\r
18 * This a class I'm writing to replace the un-cohesive operations of
\r
19 * the existing file manager.
\r
21 * The focus of these methods is security. This file manager is written
\r
22 * to be much more secure and easier to maintain then the existing code.
\r
27 * Class for dealing with files/directories in the course content directory
\r
29 * @author Joel Kronenberg
\r
34 * string $contentDirectory - the full path to this course's content directory
\r
37 var $contentDirectory; // path to content dir
\r
41 * Constructor method. Initialises variables.
\r
43 * @author Joel Kronenberg
\r
45 function FileManager( ) {
\r
46 $this->contentDirectory = AT_CONTENT_DIR . $_SESSION['course_id'];
\r
50 * Creates a directory recursivelly.
\r
52 * @param string $dir relative path and name of the directory to create.
\r
53 * dir can be a full path of a dir structure to create.
\r
54 * @return boolean whether or not the directory was created
\r
55 * @author Joel Kronenberg
\r
57 function createDirectory($dir) {
\r
58 // break $dir into the end part
\r
59 // check that the path to the new dir is safe
\r
60 // sanitise the dir name
\r
62 // Note: would it be easier to receive the path and directory name separately?
\r
67 * Copies a file or directory
\r
69 * @param string $src relative path to the source directory or file
\r
70 * @param string $dst relative path to the destination directory or file
\r
71 * @return boolean TRUE or FALSE whether or not the action was successful
\r
72 * @author Joel Kronenberg
\r
74 function copy($src, $dst) {
\r
79 * Moves a file or directory
\r
81 * @param string $src relative path to the source directory or file
\r
82 * @param string $dst relative path to the destination directory or file
\r
83 * @return boolean TRUE or FALSE whether or not the action was successful
\r
84 * @author Joel Kronenberg
\r
86 function move($src, $dst) {
\r
91 * Rename a file or directory
\r
93 * @param string $old_name relative path and old name of the directory or file to rename
\r
94 * @param string $new_name relative path and new name of the directory or file to rename
\r
95 * @return boolean TRUE or FALSE whether or not the action was successful
\r
96 * @author Joel Kronenberg
\r
98 function rename($old_name, $new_name) {
\r
103 * Delete a file or directory (recusively)
\r
105 * @param string $file relative path and name of the file or directory to delete
\r
106 * @return boolean TRUE or FALSE whether or not the action was successful
\r
107 * @author Joel Kronenberg
\r
109 function delete($file) {
\r
110 // if it's a dir, then call the $this->_deleteDir($file) private method
\r
111 // else if it's a file call the $this->_deleteFile($file) private method
\r
115 * Extracts a zip archive
\r
117 * @param string $archive relative path and name of the zip file to extract
\r
118 * @param string $dst relative path and name of the directory to extract the files into
\r
119 * @return boolean TRUE or FALSE whether or not the action was successful
\r
120 * @author Joel Kronenberg
\r
122 function extract($archive, $dst) {
\r
127 * Saves contents to a file
\r
129 * @param string $file relative path to the file to save to
\r
130 * @param string $contents the contents of the file to save to
\r
131 * @param boolean $overwrite whether or not to overwrite the file if it exists
\r
132 * @return boolean TRUE or FALSE whether or not the action was successful
\r
133 * @author Joel Kronenberg
\r
135 function saveFile($file, $contents, $overwrite = FALSE) {
\r
140 * Saves an uploded file
\r
142 * @return boolean TRUE or FALSE whether or not the action was successful
\r
143 * @author Joel Kronenberg
\r
145 function saveUploadFile( ) {
\r
150 * Returns size of a directory (recursively)
\r
152 * @param string $dir relative path to the directory
\r
153 * @param boolean $recursive whether or not to recurse down directories
\r
154 * @return int size of directory in Bytes, FALSE on failure
\r
155 * @author Joel Kronenberg
\r
157 function getDirectorySize($dir, $recursive = TRUE) {
\r
158 $dir = $this->_getRealPath($dir);
\r
160 if (($dir !== FALSE) && is_dir($dir)) {
\r
161 $dh = @opendir($dir);
\r
167 while (($file = readdir($dh)) !== false) {
\r
168 if (($file != '.') && ($file != '..')) {
\r
169 $path = $dir . $file;
\r
170 if (is_dir($path) && ($recursive === TRUE)) {
\r
171 $size += $this->getDirectorySize($path . DIRECTORY_SEPARATOR);
\r
172 } elseif (is_file($path)) {
\r
173 $size += filesize($path);
\r
183 * Returns listing of files and directories
\r
185 * @param string $dir relative path to the directory
\r
186 * @return array array of files and directories in $dir
\r
187 * @author Joel Kronenberg
\r
189 function getDirectoryListing($dir) {
\r
194 * Returns whether or not the $fileName is an editable type of file
\r
196 * @param string $fileName name of the file to check
\r
197 * @return boolean TRUE if the file can be edited, FALSE otherwise
\r
198 * @author Joel Kronenberg
\r
200 function isEditable($fileName) {
\r
201 // check if $fileName is in the list of editable files
\r
206 * Returns whether or not the $fileName is an archive that can be extracted
\r
208 * @param string $fileName name of the file to check
\r
209 * @return boolean TRUE if the file can be extracted, FALSE otherwise
\r
210 * @author Joel Kronenberg
\r
212 function isExtractable($fileName) {
\r
213 // check if $fileName is in the list of extractable files
\r
215 // Note: could possibly call this isArchive() (but that doesn't directly imply extractability)
\r
218 // -- private methods below
\r
221 * Returns a safe to use file or directory name
\r
223 * @param string $file the file or directory name to sanitise
\r
224 * @return string|boolean the sanitised file/directory name, or FALSE if the result is empty
\r
225 * @author Joel Kronenberg
\r
227 function _getCleanName($fileName) {
\r
228 $fileName = trim($fileName);
\r
229 $fileName = str_replace(' ', '_', $fileName);
\r
230 $fileName = str_replace(array(' ', '/', '\\', ':', '*', '?', '"', '<', '>', '|', '\''), '', $fileName);
\r
236 * Returns canonicalized absolute pathname
\r
238 * @param string $file the relative path to a file or directory
\r
239 * @return string|boolean the canonicalized pathname, or FALSE if the file is not in the content directory
\r
240 * @author Joel Kronenberg
\r
242 function _getRealPath($file) {
\r
243 // determine the real path of the file/directory
\r
244 $real = realpath($this->contentDirectory . DIRECTORY_SEPARATOR . $file);
\r
246 if (!file_exists($real)) {
\r
247 // the file or directory does not exist
\r
250 } else if (substr($real, 0, strlen($this->contentDirectory)) != $this->contentDirectory) {
\r
251 // the file or directory is not in the content path
\r
255 // otherwise return the real path of the file
\r
263 * @param string $file relative path and name of the file or directory to delete
\r
264 * @return boolean TRUE or FALSE whether or not the action was successful
\r
265 * @author Joel Kronenberg
\r
267 function _deleteFile($file) {
\r
272 * Delete this directory recursively
\r
274 * @param string $dir relative path and name of the directory to delete
\r
275 * @return boolean TRUE or FALSE whether or not the action was successful
\r
276 * @author Joel Kronenberg
\r
278 function _deleteDirectory($dir) {
\r
285 * FileManagerFactory
\r
286 * Class for creating AbstractFileManager Objects
\r
288 * @author Joel Kronenberg
\r
289 * @package FileManager
\r
291 class FileManagerFactory {
\r
293 function FileManagerFactory() { }
\r
295 function createFileManagerFile($name) {
\r
296 $obj = new FileManagerFile($name);
\r
297 if ($obj->isOkay()) {
\r
302 function createFileManagerDirectory($name) {
\r
303 $obj= new FileManagerDirectory($name);
\r
304 if ($obj->isOkay()) {
\r
310 function open($name) {
\r
311 if (is_dir($name)) {
\r
312 $obj = new FileManagerDirectory($name);
\r
313 } else if (is_file($name)) {
\r
314 $obj = new FileManagerFile($name);
\r
319 if ($obj->isOkay()) {
\r
326 class AbstractFileManager {
\r
327 var $_type; // private
\r
328 var $_name; // private
\r
329 var $_path; // private
\r
330 var $_filename; // private
\r
331 var $_exists; // private
\r
333 // var $_old_filename;
\r
334 // var $_old_path; // maybe?
\r
336 var $_fp; // private, file/dir pointer
\r
338 function AbstractFileManager( ) {
\r
339 $this->contentDirectory = AT_CONTENT_DIR . $_SESSION['course_id'];
\r
342 function create() { }
\r
344 function isOkay() {
\r
345 // this is where the important authentication check is done!
\r
346 echo 'authenticating '.$this->_filename.'<br>';
\r
347 if (file_exists($this->_path . DIRECTORY_SEPARATOR . $this->_filename)) {
\r
348 $this->_exists = TRUE;
\r
350 $this->_exists = FALSE;
\r
351 if ($this->isIllegalType()) {
\r
357 function exists() {
\r
358 return $this->_exists;
\r
363 class FileManagerFile extends AbstractFileManager {
\r
364 var $_extension; // private
\r
366 function FileManagerFile($file) {
\r
367 $this->_type = 'file';
\r
369 $pathinfo = pathinfo($file);
\r
370 $this->_extension = $pathinfo['extension'];
\r
371 $this->_path = $pathinfo['dirname'];
\r
372 $this->_filename = $pathinfo['basename'];
\r
374 // set whether or not this file/dir is safe.
\r
377 function rename($newName) {
\r
380 $fileManagerFactory = new FileManagerFactory();
\r
381 $fileObj = $fileManagerFactory->createFileManagerFile($this->_path . DIRECTORY_SEPARATOR . $newName);
\r
382 if (($fileObj !== NULL) && !$fileObj->exists()) {
\r
383 if (@rename($this->_path . DIRECTORY_SEPARATOR . $this->_filename, $this->_path . DIRECTORY_SEPARATOR . $newName)) {
\r
384 $this->_filename = $newName;
\r
391 function delete() {
\r
392 return unlink($this->_path . DIRECTORY_SEPARATOR . $this->_filename);
\r
395 function isIllegalType($name = '') {
\r
396 // get file extension
\r
398 $pathinfo = pathinfo($name);
\r
399 $ext = $pathinfo['extension'];
\r
401 $ext = $this->_extension;
\r
404 if (in_array($ext, array('txt', 'html'))) {
\r
410 function create($content) {
\r
411 if (!is_dir($this->_path)) {
\r
412 $fileManagerFactory = new FileManagerFactory();
\r
413 $dirObj = $fileManagerFactory->createFileManagerDirectory($this->_path);
\r
414 if ($dirObj !== NULL) {
\r
415 $dirObj->create(0666);
\r
419 // save $contents into $file
\r
421 if (($fp = @fopen($this->_path . DIRECTORY_SEPARATOR . $this->_filename, 'wb+')) !== FALSE) {
\r
422 $return = @fwrite($fp, $content, strlen($content));
\r
430 class FileManagerDirectory extends AbstractFileManager {
\r
432 function FileManagerDirectory($dir) {
\r
433 $this->_type = 'directory';
\r
435 $pathinfo = pathinfo($dir);
\r
436 $this->_path = $pathinfo['dirname'];
\r
437 $this->_filename = $pathinfo['basename'];
\r
440 function isIllegalType() {
\r
444 function getDirectoryListing() {
\r
449 function create($mode = 0666) {
\r
450 if (is_dir($this->_path)) {
\r
451 return @mkdir($this->_path . DIRECTORY_SEPARATOR . $this->_filename, $mode);
\r
453 $fileManagerFactory = new FileManagerFactory();
\r
454 $dirObj = $fileManagerFactory->createFileManagerDirectory($this->_path);
\r
455 if ($dirObj !== NULL) {
\r
456 if ($dirObj->create(0666) !== FALSE) {
\r
457 return @mkdir($this->_path . DIRECTORY_SEPARATOR . $this->_filename, $mode);
\r
463 function delete() {}
\r
465 function getDirectorySize($recursive = TRUE) {
\r
470 function _getDirectorySize($recursive = TRUE) {
\r
476 $fileManagerFactory = new FileManagerFactory();
\r
478 $fileObj = $fileManagerFactory->createFileManagerFile('/content/meow.txt');
\r
480 if ($fileObj !== NULL) {
\r
481 $data = 'stuff goes in here';
\r
482 if ($fileObj->create($data) !== FALSE) {
\r
483 echo 'create good: ' . $fileObj->_filename .' in '. $fileObj->_path;
\r
488 $fileObj = $fileManagerFactory->open('/content/meow.txt');
\r
489 if ($fileObj !== NULL) {
\r
490 if ($fileObj->rename('cow.txt') !== FALSE) {
\r
491 echo 'rename good: ' . $fileObj->_filename .' in '. $fileObj->_path;
\r
497 $fileObj = $fileManagerFactory->open('/content/cow.txt');
\r
498 if ($fileObj !== NULL) {
\r
499 if ($fileObj->delete() !== FALSE) {
\r
500 echo 'delete good: ' . $fileObj->_filename .' in '. $fileObj->_path;
\r
506 $dirObj = $fileManagerFactory->createFileManagerDirectory('/content/test1/test2/test3/test4/');
\r
507 if ($dirObj !== NULL) {
\r
508 if ($dirObj->create(0666) !== FALSE) {
\r
509 echo 'create good: ' . $dirObj->_filename .' in '. $dirObj->_path;
\r
511 echo 'dir exists: ' . $dirObj->_filename .' in '. $dirObj->_path;
\r
518 $fileObj = $fileManagerFactory->createFileManagerFile('/content/test3/test122/quack.txt');
\r
519 if ($fileObj !== NULL) {
\r
520 $data = 'quack file goes here';
\r
521 if ($fileObj->create($data) !== FALSE) {
\r
522 echo 'create good: ' . $fileObj->_filename .' in '. $fileObj->_path;
\r
529 - create/overwrite file
\r
537 - move dir (and its files)
\r