diff --git a/contrib/ext_manager/main.php b/contrib/ext_manager/main.php index 3d99dd4d..317da020 100644 --- a/contrib/ext_manager/main.php +++ b/contrib/ext_manager/main.php @@ -16,9 +16,15 @@ class ExtManager extends Extension { if(is_a($event, 'PageRequestEvent') && ($event->page_name == "ext_manager")) { if($event->user->is_admin()) { if($event->get_arg(0) == "set") { - $this->set_things($_POST); - $event->page->set_mode("redirect"); - $event->page->set_redirect("ext_manager"); + if(is_writable("ext")) { + $this->set_things($_POST); + $event->page->set_mode("redirect"); + $event->page->set_redirect(make_link("ext_manager")); + } + else { + $this->theme->display_error($event->page, "File Operation Failed", + "The extension folder isn't writable by the web server :("); + } } else { $this->theme->display_table($event->page, $this->get_extensions()); @@ -73,23 +79,34 @@ class ExtManager extends Extension { preg_match("#contrib/(.*)/main.php#", $main, $matches); $fname = $matches[1]; + if(!isset($settings["ext_$fname"])) $settings["ext_$fname"] = 0; $this->set_enabled($fname, $settings["ext_$fname"]); } } + private function set_enabled($fname, $enabled) { if($enabled) { // enable if currently disabled if(!file_exists("ext/$fname")) { - symlink("../contrib/$fname", "ext/$fname"); + $this->enable_extension($fname); } } else { // disable if currently enabled if(file_exists("ext/$fname")) { - unlink("ext/$fname"); + deltree("ext/$fname"); } } } + + private function enable_extension($fname) { + if(function_exists("symlink")) { + symlink("../contrib/$fname", "ext/$fname"); + } + else { + full_copy("contrib/$fname", "ext/$fname"); + } + } } add_event_listener(new ExtManager()); ?> diff --git a/core/util.inc.php b/core/util.inc.php index 2fcc32fb..c67402bb 100644 --- a/core/util.inc.php +++ b/core/util.inc.php @@ -364,6 +364,51 @@ function ip_in_range($IP, $CIDR) { return ($ip_ip_net == $ip_net); } +// from a patch by Christian Walde; only intended for use in the +// "extension manager" extension, but it seems to fit better here +function deltree($f) { + if (is_link($f)) { + unlink($f); + } + else if(is_dir($f)) { + foreach(glob($f.'/*') as $sf) { + if (is_dir($sf) && !is_link($sf)) { + deltree($sf); + } else { + unlink($sf); + } + } + rmdir($f); + } +} + +// from a comment on http://uk.php.net/copy +function full_copy($source, $target) { + if(is_dir($source)) { + @mkdir($target); + + $d = dir($source); + + while(FALSE !== ($entry = $d->read())) { + if($entry == '.' || $entry == '..') { + continue; + } + + $Entry = $source . '/' . $entry; + if(is_dir($Entry)) { + full_copy($Entry, $target . '/' . $entry); + continue; + } + copy($Entry, $target . '/' . $entry); + } + $d->close(); + } + else { + copy($source, $target); + } +} + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\ * Event API * \* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */