/** * This function deletes a folder and all containing files. If it's unable to delete ANYTHING - file or folder, * it halts immediately and returns false. * * This also sucks. This has failed to properly delete module folders since 2.0.0. * * @param string $folder * @return boolean */ function ft_delete_folder($directory) { if (substr($directory, -1) == '/') { $directory = substr($directory, 0, -1); } if (!file_exists($directory) || !is_dir($directory)) { return false; } elseif (is_readable($directory)) { $handle = opendir($directory); while (false !== ($item = readdir($handle))) { if ($item != '.' && $item != '..') { $path = $directory . '/' . $item; if (is_dir($path)) { ft_delete_folder($path); } else { unlink($path); } } } closedir($handle); if (!rmdir($directory)) { return false; } } return true; /* if (is_dir($folder)) { $handle = opendir($folder); } else return false; while (false !== ($file = @readdir($handle))) { if ($file != "." && $file != "..") { if (!is_dir($folder . "/" . $file)) { if (!@unlink($folder . "/" . $file)) return false; } else { @closedir($handle); ft_delete_folder($folder . '/' . $file); } } } @closedir($handle); if (!@rmdir($folder)) return false; return true; */ }
/** * Uninstalls a module from the database. * * @param integer $module_id */ function ft_uninstall_module($module_id) { global $g_table_prefix, $LANG, $g_root_dir, $g_delete_module_folder_on_uninstallation; $module_info = ft_get_module($module_id); $module_folder = $module_info["module_folder"]; if (empty($module_info)) { return false; } $success = true; $has_custom_uninstall_script = false; if (is_file("{$g_root_dir}/modules/{$module_folder}/library.php")) { @(include_once "{$g_root_dir}/modules/{$module_folder}/library.php"); $uninstall_function_name = "{$module_folder}__uninstall"; if (function_exists($uninstall_function_name)) { $has_custom_uninstall_script = true; // get the module language file contents and store the info in the $LANG global for // so it can be accessed by the uninstallation script $LANG[$module_folder] = ft_get_module_lang_file_contents($module_folder); list($success, $custom_message) = $uninstall_function_name($module_id); // if there was a custom message returned (error or notification), overwrite the default // message if (!empty($custom_message)) { $message = $custom_message; } } } // finally, if there wasn't a custom uninstallation script, or there WAS and it was successfully // run, remove the module record and any old database references if (!$has_custom_uninstall_script || $has_custom_uninstall_script && $success) { // delete the module tables mysql_query("DELETE FROM {$g_table_prefix}modules WHERE module_id = {$module_id}"); mysql_query("DELETE FROM {$g_table_prefix}module_menu_items WHERE module_id = {$module_id}"); // if this module was used in any menus, update them $query = mysql_query("\n SELECT DISTINCT menu_id\n FROM {$g_table_prefix}menu_items\n WHERE page_identifier = 'module_{$module_id}'\n "); $affected_menu_ids = array(); while ($row = mysql_fetch_assoc($query)) { $affected_menu_ids[] = $row["menu_id"]; } if (!empty($affected_menu_ids)) { mysql_query("\n DELETE FROM {$g_table_prefix}menu_items\n WHERE page_identifier = 'module_{$module_id}'\n "); // now update the orders of all affected menus foreach ($affected_menu_ids as $menu_id) { ft_update_menu_order($menu_id); } // if rows were deleted, re-cache the admin menu and update the ordering of the admin account. // ASSUMPTION: only administrator accounts can have modules as items (will need to update at some // point soon, no doubt). ft_cache_account_menu($_SESSION["ft"]["account"]["account_id"]); ft_update_menu_order($_SESSION["ft"]["account"]["menu_id"]); } // delete any hooks registered by this module ft_unregister_module_hooks($module_folder); } // now delete the entire module folder $deleted = false; if ($g_delete_module_folder_on_uninstallation) { $deleted = ft_delete_folder("{$g_root_dir}/modules/{$module_folder}"); } if ($deleted) { $message = $LANG["notify_module_uninstalled"]; } else { $message = $LANG["notify_module_uninstalled_files_not_deleted"]; } extract(ft_process_hook_calls("end", compact("module_id", "success", "message"), array("success", "message")), EXTR_OVERWRITE); return array($success, $message); }