XHTML 2 is dead. Long live XHTML 2.
[htmlpurifier.git] / extras / FSTools.php
blob17c35ee6d0f13b77aac7f39f931d55e7cd1e0d2a
1 <?php
3 /**
4 * Filesystem tools not provided by default; can recursively create, copy
5 * and delete folders. Some template methods are provided for extensibility.
7 * @note This class must be instantiated to be used, although it does
8 * not maintain state.
9 */
10 class FSTools
13 private static $singleton;
15 /**
16 * Returns a global instance of FSTools
18 static public function singleton() {
19 if (empty(FSTools::$singleton)) FSTools::$singleton = new FSTools();
20 return FSTools::$singleton;
23 /**
24 * Sets our global singleton to something else; useful for overloading
25 * functions.
27 static public function setSingleton($singleton) {
28 FSTools::$singleton = $singleton;
31 /**
32 * Recursively creates a directory
33 * @param string $folder Name of folder to create
34 * @note Adapted from the PHP manual comment 76612
36 public function mkdirr($folder) {
37 $folders = preg_split("#[\\\\/]#", $folder);
38 $base = '';
39 for($i = 0, $c = count($folders); $i < $c; $i++) {
40 if(empty($folders[$i])) {
41 if (!$i) {
42 // special case for root level
43 $base .= DIRECTORY_SEPARATOR;
45 continue;
47 $base .= $folders[$i];
48 if(!is_dir($base)){
49 $this->mkdir($base);
51 $base .= DIRECTORY_SEPARATOR;
55 /**
56 * Copy a file, or recursively copy a folder and its contents; modified
57 * so that copied files, if PHP, have includes removed
58 * @note Adapted from http://aidanlister.com/repos/v/function.copyr.php
60 public function copyr($source, $dest) {
61 // Simple copy for a file
62 if (is_file($source)) {
63 return $this->copy($source, $dest);
65 // Make destination directory
66 if (!is_dir($dest)) {
67 $this->mkdir($dest);
69 // Loop through the folder
70 $dir = $this->dir($source);
71 while ( false !== ($entry = $dir->read()) ) {
72 // Skip pointers
73 if ($entry == '.' || $entry == '..') {
74 continue;
76 if (!$this->copyable($entry)) {
77 continue;
79 // Deep copy directories
80 if ($dest !== "$source/$entry") {
81 $this->copyr("$source/$entry", "$dest/$entry");
84 // Clean up
85 $dir->close();
86 return true;
89 /**
90 * Overloadable function that tests a filename for copyability. By
91 * default, everything should be copied; you can restrict things to
92 * ignore hidden files, unreadable files, etc. This function
93 * applies to copyr().
95 public function copyable($file) {
96 return true;
99 /**
100 * Delete a file, or a folder and its contents
101 * @note Adapted from http://aidanlister.com/repos/v/function.rmdirr.php
103 public function rmdirr($dirname)
105 // Sanity check
106 if (!$this->file_exists($dirname)) {
107 return false;
110 // Simple delete for a file
111 if ($this->is_file($dirname) || $this->is_link($dirname)) {
112 return $this->unlink($dirname);
115 // Loop through the folder
116 $dir = $this->dir($dirname);
117 while (false !== $entry = $dir->read()) {
118 // Skip pointers
119 if ($entry == '.' || $entry == '..') {
120 continue;
122 // Recurse
123 $this->rmdirr($dirname . DIRECTORY_SEPARATOR . $entry);
126 // Clean up
127 $dir->close();
128 return $this->rmdir($dirname);
132 * Recursively globs a directory.
134 public function globr($dir, $pattern, $flags = NULL) {
135 $files = $this->glob("$dir/$pattern", $flags);
136 if ($files === false) $files = array();
137 $sub_dirs = $this->glob("$dir/*", GLOB_ONLYDIR);
138 if ($sub_dirs === false) $sub_dirs = array();
139 foreach ($sub_dirs as $sub_dir) {
140 $sub_files = $this->globr($sub_dir, $pattern, $flags);
141 $files = array_merge($files, $sub_files);
143 return $files;
147 * Allows for PHP functions to be called and be stubbed.
148 * @warning This function will not work for functions that need
149 * to pass references; manually define a stub function for those.
151 public function __call($name, $args) {
152 return call_user_func_array($name, $args);
157 // vim: et sw=4 sts=4