diff --git a/NEWS b/NEWS index beb44d5f..98b49205 100644 --- a/NEWS +++ b/NEWS @@ -17,6 +17,10 @@ NEWS ( CHANGELOG and HISTORY ) HTMLPurifier HTMLPurifier.php is insufficient--in such cases include HTMLPurifier.autoload.php as well to register our autoload handler (or modify your autoload function to check HTMLPurifier_Bootstrap::getPath($class)). +! Extra utility classes for testing and non-library operations can + be found in extras/. Specifically, these are FSTools and ConfigSchema. + You may find a use for these in your own project, but right now they + are highly experimental. - Autoclose now operates iteratively, i.e.
now has both span tags closed. . Plugins now get their own changelogs according to project conventions. diff --git a/extras/ConfigSchema/DirectiveParser.php b/extras/ConfigSchema/DirectiveParser.php new file mode 100644 index 00000000..068c2bad --- /dev/null +++ b/extras/ConfigSchema/DirectiveParser.php @@ -0,0 +1,10 @@ +mkdir($base); + } + $base .= DIRECTORY_SEPARATOR; + } + } + + /** + * Copy a file, or recursively copy a folder and its contents; modified + * so that copied files, if PHP, have includes removed + * @note Adapted from http://aidanlister.com/repos/v/function.copyr.php + */ + public function copyr($source, $dest) { + // Simple copy for a file + if (is_file($source)) { + return $this->copy($source, $dest); + } + // Make destination directory + if (!is_dir($dest)) { + $this->mkdir($dest); + } + // Loop through the folder + $dir = $this->dir($source); + while (false !== $entry = $dir->read()) { + // Skip pointers + if ($entry == '.' || $entry == '..') { + continue; + } + if (!$this->copyable($entry)) { + continue; + } + // Deep copy directories + if ($dest !== "$source/$entry") { + $this->copyr("$source/$entry", "$dest/$entry"); + } + } + // Clean up + $dir->close(); + return true; + } + + /** + * Overloadable function that tests a filename for copyability. By + * default, everything should be copied; you can restrict things to + * ignore hidden files, unreadable files, etc. This function + * applies to copyr(). + */ + public function copyable($file) { + return true; + } + + /** + * Delete a file, or a folder and its contents + * @note Adapted from http://aidanlister.com/repos/v/function.rmdirr.php + */ + public function rmdirr($dirname) + { + // Sanity check + if (!$this->file_exists($dirname)) { + return false; + } + + // Simple delete for a file + if ($this->is_file($dirname) || $this->is_link($dirname)) { + return $this->unlink($dirname); + } + + // Loop through the folder + $dir = $this->dir($dirname); + while (false !== $entry = $dir->read()) { + // Skip pointers + if ($entry == '.' || $entry == '..') { + continue; + } + // Recurse + $this->rmdirr($dirname . DIRECTORY_SEPARATOR . $entry); + } + + // Clean up + $dir->close(); + return $this->rmdir($dirname); + } + + /** + * Recursively globs a directory. + */ + public function globr($dir, $pattern, $flags = NULL) { + $files = $this->glob("$dir/$pattern", $flags); + foreach ($this->glob("$dir/*", GLOB_ONLYDIR) as $sub_dir) { + $sub_files = $this->globr($sub_dir, $pattern, $flags); + $files = array_merge($files, $sub_files); + } + return $files; + } + + /** + * Allows for PHP functions to be called and be stubbed. + * @warning This function will not work for functions that need + * to pass references; manually define a stub function for those. + */ + public function __call($name, $args) { + return call_user_func_array($name, $args); + } + +} diff --git a/extras/FSTools/File.php b/extras/FSTools/File.php new file mode 100644 index 00000000..d17dce6a --- /dev/null +++ b/extras/FSTools/File.php @@ -0,0 +1,85 @@ +name = $name; + $this->fs = $fs ? $fs : FSTools::singleton(); + } + + /** Returns the filename of the file. */ + public function getName() {return $this->name;} + + /** Returns directory of the file without trailing slash */ + public function getDirectory() {return $this->fs->dirname($this->name);} + + /** + * Retrieves the contents of a file + * @todo Throw an exception if file doesn't exist + */ + public function get() { + return $this->fs->file_get_contents($this->name); + } + + /** Writes contents to a file, creates new file if necessary */ + public function write($contents) { + return $this->fs->file_put_contents($this->name, $contents); + } + + /** Deletes the file */ + public function delete() { + return $this->fs->unlink($this->name); + } + + /** Returns true if file exists and is a file. */ + public function exists() { + return $this->fs->is_file($this->name); + } + + /** Returns last file modification time */ + public function getMTime() { + return $this->fs->filemtime($this->name); + } + + /** + * Chmod a file + * @note We ignore errors because of some weird owner trickery due + * to SVN duality + */ + public function chmod($octal_code) { + return @$this->fs->chmod($this->name, $octal_code); + } + + /** Opens file's handle */ + public function open($mode) { + if ($this->handle) $this->close(); + $this->handle = $this->fs->fopen($this->name, $mode); + return true; + } + + /** Closes file's handle */ + public function close() { + if (!$this->handle) return false; + $this->fs->fclose($this->handle); + $this->handle = false; + return true; + } + +} diff --git a/extras/HTMLPurifierExtras.auto.php b/extras/HTMLPurifierExtras.auto.php new file mode 100644 index 00000000..3a03d2a7 --- /dev/null +++ b/extras/HTMLPurifierExtras.auto.php @@ -0,0 +1,9 @@ + - * @version 1.0.1-modified - * @link http://aidanlister.com/repos/v/function.copyr.php - * @param string $source Source path - * @param string $dest Destination path - * @return bool Returns TRUE on success, FALSE on failure - */ - function copyr($source, $dest) { - // Simple copy for a file - if (is_file($source)) { - return $this->copy($source, $dest); - } - // Make destination directory - if (!is_dir($dest)) { - mkdir($dest); - } - // Loop through the folder - $dir = dir($source); - while (false !== $entry = $dir->read()) { - // Skip pointers - if ($entry == '.' || $entry == '..') { - continue; - } - if (!$this->copyable($entry)) { - continue; - } - // Deep copy directories - if ($dest !== "$source/$entry") { - $this->copyr("$source/$entry", "$dest/$entry"); - } - } - // Clean up - $dir->close(); - return true; - } - - /** - * Stub for PHP's built-in copy function, can be used to overload - * functionality - */ - function copy($source, $dest) { - return copy($source, $dest); - } - - /** - * Overloadable function that tests a filename for copyability. By - * default, everything should be copied; you can restrict things to - * ignore hidden files, unreadable files, etc. - */ - function copyable($file) { - return true; - } - - /** - * Delete a file, or a folder and its contents - * - * @author Aidan Lister - * @version 1.0.3 - * @link http://aidanlister.com/repos/v/function.rmdirr.php - * @param string $dirname Directory to delete - * @return bool Returns TRUE on success, FALSE on failure - */ - function rmdirr($dirname) - { - // Sanity check - if (!file_exists($dirname)) { - return false; - } - - // Simple delete for a file - if (is_file($dirname) || is_link($dirname)) { - return unlink($dirname); - } - - // Loop through the folder - $dir = dir($dirname); - while (false !== $entry = $dir->read()) { - // Skip pointers - if ($entry == '.' || $entry == '..') { - continue; - } - // Recurse - $this->rmdirr($dirname . DIRECTORY_SEPARATOR . $entry); - } - - // Clean up - $dir->close(); - return rmdir($dirname); - } - - /** - * Recursively globs a directory. - */ - function globr($dir, $pattern, $flags = NULL) { - $files = glob("$dir/$pattern", $flags); - foreach (glob("$dir/*", GLOB_ONLYDIR) as $sub_dir) { - $sub_files = $this->globr($sub_dir, $pattern, $flags); - $files = array_merge($files, $sub_files); - } - return $files; - } - -} - - +// Load useful stuff like FSTools +require_once '../extras/HTMLPurifierExtras.auto.php'; diff --git a/tests/ConfigSchema/DirectiveParserTest.php b/tests/ConfigSchema/DirectiveParserTest.php new file mode 100644 index 00000000..933c123a --- /dev/null +++ b/tests/ConfigSchema/DirectiveParserTest.php @@ -0,0 +1,7 @@ +dir = 'tmp/' . md5(uniqid(rand(), true)) . '/'; + mkdir($this->dir); + $this->oldDir = getcwd(); + + } + + function __destruct() { + FSTools::singleton()->rmdirr($this->dir); + } + + function setup() { + chdir($this->dir); + } + + function tearDown() { + chdir($this->oldDir); + } + +} diff --git a/tests/FSTools/FileTest.php b/tests/FSTools/FileTest.php new file mode 100644 index 00000000..360c12da --- /dev/null +++ b/tests/FSTools/FileTest.php @@ -0,0 +1,35 @@ +assertFalse($file->exists()); + $file->write('foobar'); + $this->assertTrue($file->exists()); + $this->assertEqual($file->get(), 'foobar'); + $file->delete(); + $this->assertFalse($file->exists()); + } + + function testGetNonExistent() { + $name = 'notfound.txt'; + $file = new FSTools_File($name); + $this->expectError(); + $this->assertFalse($file->get()); + } + + function testHandle() { + $file = new FSTools_File('foo.txt'); + $this->assertFalse($file->exists()); + $file->open('w'); + $this->assertTrue($file->exists()); + $file->close(); + } + +} + diff --git a/tests/index.php b/tests/index.php index cb5d3219..b4c992a5 100755 --- a/tests/index.php +++ b/tests/index.php @@ -32,6 +32,19 @@ htmlpurifier_parse_args($AC, $aliases); // clean out cache if necessary if ($AC['flush']) shell_exec('php ../maintenance/flush-definition-cache.php'); +// setup our own autoload for earlier PHP versions +if (!function_exists('spl_autoload_register')) { + function __autoload($class) { + return // we're using the fact that once one OR is true, the rest is skipped + HTMLPurifier_Bootstrap::autoload($class) || + HTMLPurifierExtras::autoload($class); + } +} + +// initialize and load alternative classes +require_once '../extras/HTMLPurifierExtras.auto.php'; + + // initialize and load HTML Purifier // use ?standalone to load the alterative standalone stub if ($AC['standalone']) { diff --git a/tests/test_files.php b/tests/test_files.php index 3ede3c3d..91ccf672 100644 --- a/tests/test_files.php +++ b/tests/test_files.php @@ -130,3 +130,10 @@ if ($csstidy_location) { // ... none yet +// FSTools auxiliary library + +$test_files[] = 'FSTools/FileTest.php'; + +// ConfigSchema auxiliary library + +$test_files[] = 'ConfigSchema/DirectiveParserTest.php';