Fixing PREG_BACKTRACK_LIMIT_ERROR in HTMLPurifier_Filter_ExtractStyleBlocks
[htmlpurifier.git] / extras / FSTools.php
blobce00763166b4003ad5726d05079b7f1c7bdb8f40
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 public static function singleton()
20 if (empty(FSTools::$singleton)) FSTools::$singleton = new FSTools();
21 return FSTools::$singleton;
24 /**
25 * Sets our global singleton to something else; useful for overloading
26 * functions.
28 public static function setSingleton($singleton)
30 FSTools::$singleton = $singleton;
33 /**
34 * Recursively creates a directory
35 * @param string $folder Name of folder to create
36 * @note Adapted from the PHP manual comment 76612
38 public function mkdirr($folder)
40 $folders = preg_split("#[\\\\/]#", $folder);
41 $base = '';
42 for($i = 0, $c = count($folders); $i < $c; $i++) {
43 if(empty($folders[$i])) {
44 if (!$i) {
45 // special case for root level
46 $base .= DIRECTORY_SEPARATOR;
48 continue;
50 $base .= $folders[$i];
51 if(!is_dir($base)){
52 $this->mkdir($base);
54 $base .= DIRECTORY_SEPARATOR;
58 /**
59 * Copy a file, or recursively copy a folder and its contents; modified
60 * so that copied files, if PHP, have includes removed
61 * @note Adapted from http://aidanlister.com/repos/v/function.copyr.php
63 public function copyr($source, $dest)
65 // Simple copy for a file
66 if (is_file($source)) {
67 return $this->copy($source, $dest);
69 // Make destination directory
70 if (!is_dir($dest)) {
71 $this->mkdir($dest);
73 // Loop through the folder
74 $dir = $this->dir($source);
75 while ( false !== ($entry = $dir->read()) ) {
76 // Skip pointers
77 if ($entry == '.' || $entry == '..') {
78 continue;
80 if (!$this->copyable($entry)) {
81 continue;
83 // Deep copy directories
84 if ($dest !== "$source/$entry") {
85 $this->copyr("$source/$entry", "$dest/$entry");
88 // Clean up
89 $dir->close();
90 return true;
93 /**
94 * Overloadable function that tests a filename for copyability. By
95 * default, everything should be copied; you can restrict things to
96 * ignore hidden files, unreadable files, etc. This function
97 * applies to copyr().
99 public function copyable($file)
101 return true;
105 * Delete a file, or a folder and its contents
106 * @note Adapted from http://aidanlister.com/repos/v/function.rmdirr.php
108 public function rmdirr($dirname)
110 // Sanity check
111 if (!$this->file_exists($dirname)) {
112 return false;
115 // Simple delete for a file
116 if ($this->is_file($dirname) || $this->is_link($dirname)) {
117 return $this->unlink($dirname);
120 // Loop through the folder
121 $dir = $this->dir($dirname);
122 while (false !== $entry = $dir->read()) {
123 // Skip pointers
124 if ($entry == '.' || $entry == '..') {
125 continue;
127 // Recurse
128 $this->rmdirr($dirname . DIRECTORY_SEPARATOR . $entry);
131 // Clean up
132 $dir->close();
133 return $this->rmdir($dirname);
137 * Recursively globs a directory.
139 public function globr($dir, $pattern, $flags = NULL)
141 $files = $this->glob("$dir/$pattern", $flags);
142 if ($files === false) $files = array();
143 $sub_dirs = $this->glob("$dir/*", GLOB_ONLYDIR);
144 if ($sub_dirs === false) $sub_dirs = array();
145 foreach ($sub_dirs as $sub_dir) {
146 $sub_files = $this->globr($sub_dir, $pattern, $flags);
147 $files = array_merge($files, $sub_files);
149 return $files;
153 * Allows for PHP functions to be called and be stubbed.
154 * @warning This function will not work for functions that need
155 * to pass references; manually define a stub function for those.
157 public function __call($name, $args)
159 return call_user_func_array($name, $args);
164 // vim: et sw=4 sts=4