Added Canvas 1.1.0, originally not under SCM so no historical development records...
[canvas.git] / library / File.php
blob963ae5f483c4c748dc6e23bf4f2f12877d2fc8b7
1 <?php
2 // @title File class
3 // @author Matt Todd <matt@matttoddphoto.com>
4 // @created 2006-02-06
5 // @desc Handles interaction with the filesystem.
6 // @requires stdexception.php (StdException class)
7 // @refer_to http://www.php.net/manual/en/ref.filesystem.php
9 include_once('stdexception.php');
11 // classes
12 class FSFile {
13 public $filename = null;
14 public $mode = "a"; // append by default (a+ for append and read)
15 public $file = null;
16 public $exists = false;
17 public $filesize = 0;
19 // constructor
20 public function __construct($filename = null, $mode = null) {
21 if(!empty($filename)) $this->open($filename, $mode);
24 // functions
25 public function open($filename = null, $mode = null) {
26 // make sure there's a filename to open
27 if($filename == null) $filename = $this->filename;
28 if($filename == null) return null; // return null if none present to open
29 // get reading/writing mode
30 if($mode == null) $mode = $this->mode;
32 // if it doens't exist, return null
33 if(file_exists($filename)) $this->exists = true; else throw new FileDoesNotExistException(); // return null; // decided to throw an exception
35 // get filesize
36 $this->filesize = filesize($filename);
38 // open the file (returning the handle to $this->file)
39 $this->file = @fopen($filename, $mode);
40 if($this->file == null) throw new FileNotOpenException();
43 public function close() {
44 // close the file
45 return @fclose($this->file);
48 // reading and writing functions
49 public function read() {
50 // check for existence and whether it's open
51 if(!$this->exists) return false;
52 if($this->file == null) $this->open();
53 if($this->file == null) return false;
55 // read and return everything
56 return fread($this->file, $this->filesize);
58 public function write($data) {
59 // check for existence and whether it's open
60 if(!$this->exists) return false;
61 if($this->file == null) $this->open();
62 if($this->file == null) return false;
64 // write to the file (following the guidelines of the writing mode)
65 $bytes_written = @fwrite($this->file, $data);
67 // return true if the number of bytes written is greater than zero, or the same size as the source data
68 if(($bytes_written > 0) || (strlen($data) == $bytes_written))
69 return true;
70 else
71 return false;
74 // uploading functions
75 public static function upload($file, $destination, $id = null) {
76 if(!is_uploaded_file($file['tmp_name'])) return false;
78 // destination
79 $destination = self::build_path($destination, self::sanitize_filename($file['name'], $id));
81 // if the file exists, throw an exception!
82 if(file_exists($destination)) throw new FileExistsAlreadyException("'{$destination}' already exists!");
84 if(move_uploaded_file($file['tmp_name'], $destination)) {
85 return true;
86 } else {
87 return false; // @consider maybe throw an exception?
91 // file management functions
92 public static function delete($location, $filename) {
93 // get full filename
94 $filename = self::build_path($location, $filename);
96 // check for existence
97 if(!file_exists($filename)) return false;
99 // delete (aka unlink) file
100 if(!@unlink($filename)) return false;
101 return true;
103 public function remove($filename = null) {
104 // check for existence and whether it's open
105 if(!$this->exists) return false;
106 if($this->file == null) $this->open();
107 if($this->file == null) return false;
109 if(!@unlink($this->filename)) return false;
110 return true;
113 // useful static functions
114 public static function sanitize_filename($filename, $id = null) {
115 // haha, 'sanitize'
116 $filename_info = pathinfo($filename);
117 $filename = str_replace(' ', '_', substr($filename_info['basename'], 0, -(strlen($filename_info['extension']) + ($filename_info['extension'] == '' ? 0 : 1))));
118 return $filename . ($id ? ('_' . $id) : '') . ($filename_info['extension'] ? ".{$filename_info[extension]}" : '');
121 public static function current_dir() {
122 $working_dir = $GLOBALS['working_dir']; // set in Dispatcher // find a better way to do this!
123 return $working_dir . '/';
126 public static function build_path($dir, $filename = '') {
127 return self::current_dir() . $dir . '/' . $filename;
130 // directory functions
131 public static function dir_listing($source_dir = null) {
132 if($source_dir == null) $source_dir = self::current_dir();
133 $dir = dir($source_dir);
134 while (false !== ($file = $dir->read())) {
135 if($file != '.' && $file != '..' && !is_dir($source_dir . $file)) {
136 $files[] = $file;
140 return $files;
143 // descructor
144 public function __destruct() {
145 $this->close();
149 class FileException extends StdException {
150 // hopefully won't ever need to be used, but you never know
152 class FileNotOpenException extends StdException {}
153 class FileDoesNotExistException extends StdException {}