From be8e898d23a3f9ca515f59fbcc8d82e112ed7ee8 Mon Sep 17 00:00:00 2001
From: Dries Buytaert <dries@buytaert.net>
Date: Sat, 5 May 2001 13:57:29 +0000
Subject: [PATCH] - Uhm.  Rewrote the module system: less code clutter, less
 run-time   overhead, and a lot better (simpler) module API.  I had to edit a 
  LOT of files to get this refactored but I'm sure it was worth the   effort.

  For module writers / maintainers:

  None of the hooks changed, so 95% of the old modules should still
  work.  You can remove some code instead as "$module = array(...)"
  just became obsolete.  Also - and let's thank God for this - the
  global variable "$repository" has been eliminated to avoid modules
  relying on, and poking in drupal's internal data structures.  Take
  a look at include/module.inc to investigate the details/changes.

- Improved design of the content modules "story", "book" and "node"
  (to aid smooth integration of permisions + moderate.module).  I'm
  still working on the permissions but I got side tracked for which
  I "Oops!".
---
 account.php                      | 22 +++-----
 admin.php                        | 21 ++-----
 cron.php                         |  9 +--
 export                           |  4 +-
 includes/common.inc              |  3 +-
 includes/module.inc              | 96 +++++++++++++++++++-------------
 includes/search.inc              |  2 +-
 includes/theme.inc               | 27 ++++-----
 module.php                       |  2 +-
 modules/account.module           |  8 +--
 modules/block.module             | 10 +---
 modules/block/block.module       | 10 +---
 modules/book.module              | 23 +++-----
 modules/book/book.module         | 23 +++-----
 modules/box.module               |  8 +--
 modules/calendar.class           |  2 -
 modules/calendar.module          |  2 -
 modules/comment.module           |  3 -
 modules/comment/comment.module   |  3 -
 modules/cron.module              |  6 +-
 modules/cvs.module               |  4 --
 modules/diary.module             | 10 ----
 modules/drupal.module            |  2 -
 modules/drupal/drupal.module     |  2 -
 modules/forum.module             |  3 -
 modules/forum/forum.module       |  3 -
 modules/headline.module          | 11 +---
 modules/headlineRSS10.module     |  7 ---
 modules/help.module              | 11 ++--
 modules/help/help.module         | 11 ++--
 modules/locale.module            |  4 --
 modules/locale/locale.module     |  4 --
 modules/moderate.module          | 31 +++++------
 modules/module.module            | 29 +++-------
 modules/node.module              | 11 +++-
 modules/node/node.module         | 11 +++-
 modules/page.module              |  2 -
 modules/page/page.module         |  2 -
 modules/queue.module             |  3 -
 modules/rating.module            |  5 --
 modules/settings.module          |  8 +--
 modules/story.module             | 14 +----
 modules/story/story.module       | 14 +----
 modules/structure.module         |  6 +-
 modules/watchdog.module          |  4 --
 modules/watchdog/watchdog.module |  4 --
 search.php                       |  4 +-
 submit.php                       |  2 +-
 48 files changed, 172 insertions(+), 334 deletions(-)

diff --git a/account.php b/account.php
index ce72b27ba88a..6490c0d18c88 100644
--- a/account.php
+++ b/account.php
@@ -186,13 +186,6 @@ function account_content_save($edit) {
 function account_user($uname) {
   global $user, $status, $theme;
 
-  function module($name, $module, $username) {
-    global $theme;
-    if ($module[account] && $block = $module[account]($username, "account", "view")) {
-      if ($block[content]) $theme->box($block[subject], $block[content]);
-    }
-  }
-
   if ($user->id && $user->userid == $uname) {
     $output .= "<TABLE BORDER=\"0\" CELLPADDING=\"2\" CELLSPACING=\"2\">\n";
     $output .= " <TR><TD ALIGN=\"right\"><B>". t("Username") .":</B></TD><TD>$user->userid</TD></TR>\n";
@@ -208,17 +201,16 @@ function module($name, $module, $username) {
     $theme->footer();
   }
   elseif ($uname && $account = account_get_user($uname)) {
-    $block1 .= "<TABLE BORDER=\"0\" CELLPADDING=\"1\" CELLSPACING=\"1\">\n";
-    $block1 .= " <TR><TD ALIGN=\"right\"><B>". t("Username") .":</B></TD><TD>$account->userid</TD></TR>\n";
-    $block1 .= " <TR><TD ALIGN=\"right\"><B>". t("E-mail") .":</B></TD><TD>". format_email($account->fake_email) ."</TD></TR>\n";
-    $block1 .= " <TR><TD ALIGN=\"right\"><B>". t("Homepage") .":</B></TD><TD>". format_url($account->url) ."</TD></TR>\n";
-    $block1 .= " <TR><TD ALIGN=\"right\"><B>". t("Bio") .":</B></TD><TD>". check_output($account->bio) ."</TD></TR>\n";
-    $block1 .= "</TABLE>\n";
+    $output .= "<TABLE BORDER=\"0\" CELLPADDING=\"1\" CELLSPACING=\"1\">\n";
+    $output .= " <TR><TD ALIGN=\"right\"><B>". t("Username") .":</B></TD><TD>$account->userid</TD></TR>\n";
+    $output .= " <TR><TD ALIGN=\"right\"><B>". t("E-mail") .":</B></TD><TD>". format_email($account->fake_email) ."</TD></TR>\n";
+    $output .= " <TR><TD ALIGN=\"right\"><B>". t("Homepage") .":</B></TD><TD>". format_url($account->url) ."</TD></TR>\n";
+    $output .= " <TR><TD ALIGN=\"right\"><B>". t("Bio") .":</B></TD><TD>". check_output($account->bio) ."</TD></TR>\n";
+    $output .= "</TABLE>\n";
 
     // Display account information:
     $theme->header();
-    if ($block1) $theme->box(strtr(t("%a's user information"), array("%a" => $uname)), $block1);
-    module_iterate("module", $uname);
+    $theme->box(strtr(t("%a's user information"), array("%a" => $uname)), $output);
     $theme->footer();
   }
   else {
diff --git a/admin.php b/admin.php
index c9085ea11166..33f89dd7662f 100644
--- a/admin.php
+++ b/admin.php
@@ -10,11 +10,11 @@ function status($message) {
 }
 
 function admin_page($mod) {
-  global $repository, $menu, $modules, $user;
+  global $menu, $user;
 
-  function module($name, $module) {
-    global $menu, $modules, $user;
-    if ($module["admin"] && user_access($user, $name)) $output .= "<A HREF=\"admin.php?mod=$name\">$name</A> | ";
+  function module($name) {
+    global $menu, $user;
+    if (function_exists($name. "_admin") && user_access($user, $name)) $output .= "<A HREF=\"admin.php?mod=$name\">$name</A> | ";
     $menu .= $output;
   }
 
@@ -32,18 +32,9 @@ function module($name, $module) {
    </STYLE>
    <BODY BGCOLOR="#FFFFFF" LINK="#005599" VLINK="#004499" ALINK="#FF0000">
     <H1>Administration</H1>
- <?php
-
-  ksort($repository);
-  module_iterate("module");
-
- ?>
+    <?php module_iterate("module"); ?>
     <HR><?php echo $menu; ?><A HREF="index.php">home</A><HR>
- <?php
-
-  if (user_access($user, $mod)) module_execute($mod, "admin");
-
- ?>
+    <?php if (user_access($user, $mod)) module_invoke($mod, "admin"); ?>
   </BODY>
  </HTML>
  <?php
diff --git a/cron.php b/cron.php
index d2d2ece5b82a..148a3b492137 100644
--- a/cron.php
+++ b/cron.php
@@ -3,16 +3,9 @@
 include_once "includes/common.inc";
 
 function cron_run() {
-  global $repository;
-
   $time = time();
-
   $result = db_query("SELECT * FROM crons WHERE $time - timestamp > scheduled");
-
-  while ($task = db_fetch_object($result)) {
-    if ($repository[$task->module]["cron"]) $repository[$task->module]["cron"]();
-  }
-
+  while ($task = db_fetch_object($result)) module_invoke($task->module, "cron");
   db_query("UPDATE crons SET timestamp = $time WHERE $time - timestamp > scheduled");
 }
 
diff --git a/export b/export
index bca0d12bb91a..50e402ea4eda 100644
--- a/export
+++ b/export
@@ -2,9 +2,9 @@
 
 include_once "includes/common.inc";
 
-function export($name, $module) {
+function export($name) {
   global $REQUEST_URI;
-  module_execute($name, "export", explode("/", $REQUEST_URI));
+  module_invoke($name, "export", explode("/", $REQUEST_URI));
 }
 
 module_iterate("export");
diff --git a/includes/common.inc b/includes/common.inc
index a8b6f6769d18..ca942f5d23d3 100644
--- a/includes/common.inc
+++ b/includes/common.inc
@@ -24,7 +24,7 @@ function throttle($type, $rate) {
     if ($throttle = db_fetch_object(db_query("SELECT * FROM watchdog WHERE type = '$type' AND hostname = '". getenv("REMOTE_ADDR") ."' AND ". time() ." - timestamp < $rate"))) {
       watchdog("warning", "throttle: '". getenv("REMOTE_ADDR") ."' exceeded submission rate - $throttle->type");
       header("Location: error.php?op=throttle");
-      exit();
+      die("submission rate exceeded");
     }
     else {
       watchdog($type, "throttle control");
@@ -196,6 +196,7 @@ function form_submit($value) {
 include_once "includes/node.inc";
 
 user_init();
+module_init();
 $locale = locale_init();
 $conf = variable_init();
 $theme = theme_init();
diff --git a/includes/module.inc b/includes/module.inc
index a23d142a0914..732584861698 100644
--- a/includes/module.inc
+++ b/includes/module.inc
@@ -1,28 +1,60 @@
 <?php
 
-// applies function $function to every known module:
+// initialize modules:
+function module_init() {
+  module_list();
+}
+
+// apply function $function to every known module:
 function module_iterate($function, $argument = "") {
-  global $repository;
-  foreach ($repository as $name=>$module) {
-    $function($name, $module, $argument);
+  foreach (module_list() as $name) $function($name, $argument);
+}
+
+// invoke hook $hook of module $name with optional arguments:
+function module_invoke($name, $hook, $argument = "") {
+  $function = $name ."_". $hook;
+  if (function_exists($function)) return $function($argument);
+}
+
+// return true if module $name supports hook $hook, and false otherwise:
+function module_is_hook($name, $hook) {
+  return function_exists($name ."_". $hook);
+}
+
+// return an array of module names (includes lazy module loading):
+function module_list() {
+  static $list;
+
+  if (!$list) {
+    $handle = opendir("modules");
+    $list = array();
+    while ($file = readdir($handle)) {
+      if (".module" == substr($file, -7)) {
+        $filename = substr($file, 0, -7);
+        include "modules/$filename.module";
+        $list[$filename] = $filename;
+      }
+    }
+    closedir($handle);
   }
+
+  return $list;
 }
 
-// executes hook $hook of module $module with optional arguments:
-function module_execute($module, $hook, $argument = "") {
-  global $repository;
-  return ($repository[$module][$hook]) ? $repository[$module][$hook]($argument) : "";
+// return 1 if module $name exists, 0 otherwise:
+function module_exist($name) {
+  $list = module_list();
+  return ($list[$name]) ? 1 : 0;
 }
 
-// returns true if module $module supports hook $hook, and false otherwise:
-function module_hook($module, $hook) {
-  global $repository;
-  return $repository[$module][$hook];
+// return 1 if module $name implements hook $hook, 0 otherwise:
+function module_hook($name, $hook) {
+  return function_exists($name ."_". $hook);
 }
 
-// rehashes the crons:
-function module_rehash_crons($name, $module) {
-  if ($module["cron"]) {
+// rehash module-exported crons:
+function module_rehash_crons($name) {
+  if (module_hook($name, "cron")) {
     if (!db_fetch_object(db_query("SELECT * FROM crons WHERE module = '$name'"))) {
       db_query("INSERT INTO crons (module, scheduled, timestamp) VALUES ('$name', '172800', '0')");
     }
@@ -32,10 +64,10 @@ function module_rehash_crons($name, $module) {
   }
 }
 
-// rehashes the blocks:
-function module_rehash_blocks($name, $module) {
+// rehash module-exported blocks:
+function module_rehash_blocks($name) {
   db_query("UPDATE blocks SET remove = '1' WHERE module = '$name'");
-  if ($module["block"] && $blocks = $module["block"]()) {
+  if ($blocks = module_invoke($name, "block")) {
     foreach ($blocks as $offset=>$block) {
       foreach ($block as $item=>$data) {
         $block[$item] = addslashes($data);
@@ -51,22 +83,20 @@ function module_rehash_blocks($name, $module) {
   db_query("DELETE FROM blocks WHERE module = '$name' AND remove = '1'");
 }
 
-// rehashes a module:
+// rehash a module:
 function module_rehash($name) {
-  global $repository;
-
-  if ($module = $repository[$name]) {
+  if (module_exist($name)) {
     $result = db_query("SELECT * FROM modules WHERE name = '$name'");
 
     if (!$object = db_fetch_object($result)) {
       db_query("INSERT INTO modules (name) VALUES ('$name')");
     }
 
-    // rehash crons (if necessary):
-    module_rehash_crons($name, $module);
+    // rehash module-exported crons (if necessary):
+    module_rehash_crons($name);
 
-    // rehash blocks (if necessary):
-    module_rehash_blocks($name, $module);
+    // rehash module-exported blocks (if necessary):
+    module_rehash_blocks($name);
   }
   else {
     // remove all reference to module:
@@ -76,16 +106,4 @@ function module_rehash($name) {
   }
 }
 
-// load modules into repository:
-$handle = opendir("modules");
-$repository = array();
-while ($file = readdir($handle)) {
-  if (".module" == substr($file, -7)) {
-    $filename = substr($file, 0, -7);
-    include "modules/$filename.module";
-    $repository[$filename] = $module;
-  }
-}
-closedir($handle);
-
-?>
+?>
\ No newline at end of file
diff --git a/includes/search.inc b/includes/search.inc
index 851bc3a3a762..99ed78d7465d 100644
--- a/includes/search.inc
+++ b/includes/search.inc
@@ -11,7 +11,7 @@ function search_form($keys) {
 
 function search_data($keys, $type) {
   if ($keys && $type) {
-    $result = module_execute($type, "find", check_input($keys));
+    $result = module_invoke($type, "find", check_input($keys));
     foreach ($result as $entry) {
       $output .= "<P>\n";
       $output .= " <B><U><A HREF=\"$entry[link]\">$entry[title]</A></U></B><BR>";
diff --git a/includes/theme.inc b/includes/theme.inc
index 793824d064dc..8af929744494 100644
--- a/includes/theme.inc
+++ b/includes/theme.inc
@@ -13,31 +13,22 @@ function theme_init() {
 }
 
 function theme_link($separator = " | ") {
-  global $repository;
   $links[] = "<A HREF=\"index.php\">". t("home") ."</A>";
   $links[] = "<A HREF=\"search.php\">". t("search") ."</A>";
   $links[] = "<A HREF=\"submit.php\">". t("submit") ."</A>";
-  if ($repository[forum]) $links[] = "<A HREF=\"module.php?mod=forum\">".t("forum") ."</A>";
-  if ($repository[diary]) $links[] = "<A HREF=\"module.php?mod=diary\">". t("diary") ."</A>";
   $links[] = "<A HREF=\"account.php\">". t("account") ."</A>";
-  if ($repository[book]) $links[] = "<A HREF=\"module.php?mod=book\">". t("handbook") ."</A>";
+  if (module_exist("forum")) $links[] = "<A HREF=\"module.php?mod=forum\">".t("forum") ."</A>";
+  if (module_exist("diary")) $links[] = "<A HREF=\"module.php?mod=diary\">". t("diary") ."</A>";
+  if (module_exist("book")) $links[] = "<A HREF=\"module.php?mod=book\">". t("handbook") ."</A>";
 
   return implode($separator, $links);
 }
 
-function theme_menu($name, $module) {
-  global $menu;
-  if ($module["menu"]) $menu = ($menu) ? array_merge($menu, $module["menu"]()) : $module["menu"]();
-}
 
 function theme_account($theme) {
-  global $user, $links, $menu;
+  global $user;
 
   if ($user->id) {
-
-
-    module_iterate("theme_menu");
-
     // Display account settings:
     $content .= "<LI><A HREF=\"account.php?op=track&topic=comments\">". t("track your comments") ."</A></LI>\n";
     $content .= "<LI><A HREF=\"account.php?op=track&topic=nodes\">". t("track your nodes") ."</A></LI>\n";
@@ -53,10 +44,12 @@ function theme_account($theme) {
       $content .= "<P>\n";
     }
 
-    if ($menu) {
-      foreach ($menu as $link) $content .= "<LI>$link</LI>\n";
-      $content .= "<P>\n";
+    foreach (module_list() as $name) {
+      if ($links = module_invoke($name, "menu")) {
+        foreach ($links as $link) $content .= "<LI>$link</LI>\n";
+      }
     }
+    if ($link) $content .= "<P>\n";
 
     $content .= "<LI><A HREF=\"account.php?op=logout\">". t("logout") ."</A></LI>\n";
 
@@ -92,7 +85,7 @@ function theme_blocks($region, $theme) {
       if ($user->id) $result = db_query("SELECT * FROM blocks b LEFT JOIN layout l ON b.name = l.block WHERE (b.status = 2 OR (b.status = 1 AND l.user = '$user->id'))". (($region == "left" || $region == "right") ? ($region == "left" ? " AND b.region = 0" : " AND b.region = 1") : "") ." ORDER BY weight");
       else $result = db_query("SELECT * FROM blocks WHERE status = 2". (($region == "left" || $region == "right") ? ($region == "left" ? " AND region = 0" : " AND region = 1") : "") ." ORDER BY weight");
       while ($block = db_fetch_object($result)) {
-        $blocks = module_execute($block->module, "block");
+        $blocks = module_invoke($block->module, "block");
         $theme->box(t($blocks[$block->offset]["subject"]), $blocks[$block->offset]["content"]);
       }
       break;
diff --git a/module.php b/module.php
index 859315a704c2..4dff9fe3fd80 100644
--- a/module.php
+++ b/module.php
@@ -2,7 +2,7 @@
 
 include_once "includes/common.inc";
 if (variable_get(dev_timing, 0)) timer_start();
-module_execute($mod, "page");
+module_invoke($mod, "page");
 if (variable_get(dev_timing, 0)) timer_print();
 
 ?>
diff --git a/modules/account.module b/modules/account.module
index aeb1f3fc241e..8480e540fed7 100644
--- a/modules/account.module
+++ b/modules/account.module
@@ -1,9 +1,5 @@
 <?php
 
-$module = array("help" => "account_help",
-                "find" => "account_find",
-                "admin" => "account_admin");
-
 function account_help() {
  ?>
   <P>The account-module is responsible for maintaining the user database. It automatically handles tasks like registration, authentication, access control, password retrieval, user settings and much more.</P>
@@ -153,9 +149,9 @@ function account_edit_save($name, $edit) {
 function account_edit($name) {
   global $access, $account;
 
-  function access($name, $module) {
+  function access($name) {
     global $access, $account;
-    if ($module["admin"]) $access .= "<OPTION VALUE=\"$name\"". (user_access($account, $name) ? " SELECTED" : "") .">$name</OPTION>";
+    if (module_hook($name, "admin")) $access .= "<OPTION VALUE=\"$name\"". (user_access($account, $name) ? " SELECTED" : "") .">$name</OPTION>";
   }
 
   $status = array("blocked", "not confirmed", "open");
diff --git a/modules/block.module b/modules/block.module
index c2b53240be81..b37c8fb89d6f 100644
--- a/modules/block.module
+++ b/modules/block.module
@@ -1,9 +1,5 @@
 <?php
 
-$module = array("page" => "block_page",
-                "help" => "block_help",
-                "admin" => "block_admin");
-
 function block_help() {
  ?>
   <P>Blocks are the boxes visible in the side bars on the left- and right-hand side of the website.  They are either exported by the engine or by any of the active modules.  To really get your teeth into a drupal website, you are going to have to deal with blocks and administering blocks in a fairly sophisticated fashion.  This means you will need to understand how the block placement strategy works.</P>
@@ -23,7 +19,7 @@ function block_page() {
   while ($block = db_fetch_object($result)) {
     if ($state % 3 == 0) print " <TR>\n";
     print "  <TD ALIGN=\"center\" VALIGN=\"top\" WIDTH=\"33%\">\n";
-    $blocks = module_execute($block->module, "block");
+    $blocks = module_invoke($block->module, "block");
     $theme->box($blocks[$block->offset]["subject"], $blocks[$block->offset]["content"]);
     print " </TD>\n";
     if ($state % 3 == 2) print " </TR>\n";
@@ -40,8 +36,6 @@ function block_admin_save($edit) {
 }
 
 function block_admin_display() {
-  global $repository;
-
   $result = db_query("SELECT * FROM blocks ORDER BY module");
 
   // Generate output:
@@ -50,7 +44,7 @@ function block_admin_display() {
   $output .= " <TR><TH>block</TH><TH>module</TH><TH>status</TH><TH>weight</TH><TH>region</TH></TR>\n";
 
   while ($block = db_fetch_object($result)) {
-    $module = ($repository[$block->module]["admin"]) ? "<A HREF=\"admin.php?mod=$block->module\">$block->module</A>" : $block->module;
+    $module = module_hook($block->module, "admin") ? "<A HREF=\"admin.php?mod=$block->module\">$block->module</A>" : $block->module;
 
     $status .= "<SELECT NAME=\"edit[$block->name][status]\">\n";
     $status .= " <OPTION VALUE=\"2\"". (($block->status == 2) ? " SELECTED" : "") .">enabled: always</OPTION>\n";
diff --git a/modules/block/block.module b/modules/block/block.module
index c2b53240be81..b37c8fb89d6f 100644
--- a/modules/block/block.module
+++ b/modules/block/block.module
@@ -1,9 +1,5 @@
 <?php
 
-$module = array("page" => "block_page",
-                "help" => "block_help",
-                "admin" => "block_admin");
-
 function block_help() {
  ?>
   <P>Blocks are the boxes visible in the side bars on the left- and right-hand side of the website.  They are either exported by the engine or by any of the active modules.  To really get your teeth into a drupal website, you are going to have to deal with blocks and administering blocks in a fairly sophisticated fashion.  This means you will need to understand how the block placement strategy works.</P>
@@ -23,7 +19,7 @@ function block_page() {
   while ($block = db_fetch_object($result)) {
     if ($state % 3 == 0) print " <TR>\n";
     print "  <TD ALIGN=\"center\" VALIGN=\"top\" WIDTH=\"33%\">\n";
-    $blocks = module_execute($block->module, "block");
+    $blocks = module_invoke($block->module, "block");
     $theme->box($blocks[$block->offset]["subject"], $blocks[$block->offset]["content"]);
     print " </TD>\n";
     if ($state % 3 == 2) print " </TR>\n";
@@ -40,8 +36,6 @@ function block_admin_save($edit) {
 }
 
 function block_admin_display() {
-  global $repository;
-
   $result = db_query("SELECT * FROM blocks ORDER BY module");
 
   // Generate output:
@@ -50,7 +44,7 @@ function block_admin_display() {
   $output .= " <TR><TH>block</TH><TH>module</TH><TH>status</TH><TH>weight</TH><TH>region</TH></TR>\n";
 
   while ($block = db_fetch_object($result)) {
-    $module = ($repository[$block->module]["admin"]) ? "<A HREF=\"admin.php?mod=$block->module\">$block->module</A>" : $block->module;
+    $module = module_hook($block->module, "admin") ? "<A HREF=\"admin.php?mod=$block->module\">$block->module</A>" : $block->module;
 
     $status .= "<SELECT NAME=\"edit[$block->name][status]\">\n";
     $status .= " <OPTION VALUE=\"2\"". (($block->status == 2) ? " SELECTED" : "") .">enabled: always</OPTION>\n";
diff --git a/modules/book.module b/modules/book.module
index f0e9d4c44607..550da76a990a 100644
--- a/modules/book.module
+++ b/modules/book.module
@@ -1,20 +1,11 @@
 <?php
 
-$module = array("find" => "book_find",
-                "page" => "book_page",
-                "user" => "book_user",
-                "admin" => "book_admin",
-                "export" => "book_export");
-
 class Book {
-  function Book($nid, $userid, $title, $body, $parent, $weight, $timestamp) {
-    $this->nid = $nid;
-    $this->userid = $userid;
-    $this->title = $title;
-    $this->body = $body;
-    $this->parent = $parent;
-    $this->weight = $weight;
-    $this->timestamp = $timestamp;
+  function Book($book) {
+    $this = new Node($book);
+    $this->body = $book[body];
+    $this->parent = $book[parent];
+    $this->weight = $book[weight];
   }
 }
 
@@ -184,7 +175,7 @@ function book_admin() {
       print book_tree();
       break;
     case t("Preview"):
-      book_view(new Book(($edit[nid] ? $edit[nid] : -1), ($edit[userid] ? $edit[userid] : $user->userid), $edit[title], $edit[body], $edit[parent], $edit[weight], ($edit[timestamp] ? $edit[timestamp] : time())));
+      book_view(new Book($edit));
       print book_form($edit);
       break;
     case t("Submit"):
@@ -235,7 +226,7 @@ function book_user() {
       $theme->box($title, book_update($id));
       break;
     case t("Preview"):
-      book_view(new Book(($edit[nid] ? $edit[nid] : -1), $user->userid, $edit[title], $edit[body], $edit[parent], $edit[weight], ($edit[timestamp] ? $edit[timestamp] : time())));
+      book_view(new Book($edit));
       $theme->box($title, book_form($edit));
       break;
     case t("Submit"):
diff --git a/modules/book/book.module b/modules/book/book.module
index f0e9d4c44607..550da76a990a 100644
--- a/modules/book/book.module
+++ b/modules/book/book.module
@@ -1,20 +1,11 @@
 <?php
 
-$module = array("find" => "book_find",
-                "page" => "book_page",
-                "user" => "book_user",
-                "admin" => "book_admin",
-                "export" => "book_export");
-
 class Book {
-  function Book($nid, $userid, $title, $body, $parent, $weight, $timestamp) {
-    $this->nid = $nid;
-    $this->userid = $userid;
-    $this->title = $title;
-    $this->body = $body;
-    $this->parent = $parent;
-    $this->weight = $weight;
-    $this->timestamp = $timestamp;
+  function Book($book) {
+    $this = new Node($book);
+    $this->body = $book[body];
+    $this->parent = $book[parent];
+    $this->weight = $book[weight];
   }
 }
 
@@ -184,7 +175,7 @@ function book_admin() {
       print book_tree();
       break;
     case t("Preview"):
-      book_view(new Book(($edit[nid] ? $edit[nid] : -1), ($edit[userid] ? $edit[userid] : $user->userid), $edit[title], $edit[body], $edit[parent], $edit[weight], ($edit[timestamp] ? $edit[timestamp] : time())));
+      book_view(new Book($edit));
       print book_form($edit);
       break;
     case t("Submit"):
@@ -235,7 +226,7 @@ function book_user() {
       $theme->box($title, book_update($id));
       break;
     case t("Preview"):
-      book_view(new Book(($edit[nid] ? $edit[nid] : -1), $user->userid, $edit[title], $edit[body], $edit[parent], $edit[weight], ($edit[timestamp] ? $edit[timestamp] : time())));
+      book_view(new Book($edit));
       $theme->box($title, book_form($edit));
       break;
     case t("Submit"):
diff --git a/modules/box.module b/modules/box.module
index 789185cc52ee..5edc748ac170 100644
--- a/modules/box.module
+++ b/modules/box.module
@@ -1,10 +1,5 @@
 <?php
 
-$module = array("help" => "box_help",
-                "block" => "box_block",
-                "admin" => "box_admin");
-
-
 function box_help() {
  ?>
   <P>The content of the site can be almost entirely altered through <I>boxes</I>.  Simply put, boxes are small bits of text, HTML or PHP code which will get plugged into the site just like any other block.  Boxes are typically used to add custom blocks to the site.</P>
@@ -96,8 +91,7 @@ function box_admin_delete($id) {
 }
 
 function box_admin_rehash() {
-  global $repository;
-  module_rehash_blocks("box", $repository["box"]);
+  module_rehash_blocks("box");
 }
 
 function box_admin_edit($id) {
diff --git a/modules/calendar.class b/modules/calendar.class
index 340b62139201..b6595b360f1b 100644
--- a/modules/calendar.class
+++ b/modules/calendar.class
@@ -1,7 +1,5 @@
 <?php
 
-$module = array();
-
 class Calendar {
   var $date;
 
diff --git a/modules/calendar.module b/modules/calendar.module
index 145fc7de003f..23b600793351 100644
--- a/modules/calendar.module
+++ b/modules/calendar.module
@@ -1,7 +1,5 @@
 <?php
 
-$module = array("block" => "calendar_block");
-
 function calendar_block() {
   global $date;
 
diff --git a/modules/comment.module b/modules/comment.module
index c8f14006f9e6..9af8d04e8c50 100644
--- a/modules/comment.module
+++ b/modules/comment.module
@@ -1,8 +1,5 @@
 <?php
 
-$module = array("find" => "comment_find",
-                "admin" => "comment_admin");
-
 function comment_find($keys) {
   global $user;
   $find = array();
diff --git a/modules/comment/comment.module b/modules/comment/comment.module
index c8f14006f9e6..9af8d04e8c50 100644
--- a/modules/comment/comment.module
+++ b/modules/comment/comment.module
@@ -1,8 +1,5 @@
 <?php
 
-$module = array("find" => "comment_find",
-                "admin" => "comment_admin");
-
 function comment_find($keys) {
   global $user;
   $find = array();
diff --git a/modules/cron.module b/modules/cron.module
index d34a2f291e42..97b59a10e69d 100644
--- a/modules/cron.module
+++ b/modules/cron.module
@@ -1,8 +1,5 @@
 <?php
 
-$module = array("help" => "cron_help",
-                "admin" => "cron_admin");
-
 function cron_help() {
  ?>
   <P>Cron (which stands for chronograph) is a periodic command scheduler: it executes commands at intervals specified in seconds.  It can be used to control the execution of daily, weekly and monthly jobs (or anything with a period of <i>n</i> seconds).   Automating tasks is one of the best ways to keep a system running smoothly, and if most of your administration does not require your direct involvement, cron is an ideal solution.</P>
@@ -18,9 +15,8 @@ function cron_save($edit) {
 }
 
 function cron_execute($name) {
-  global $repository;
   watchdog("message", "cron: executed '". $name ."_cron()'");
-  $repository[$name]["cron"]();
+  module_invoke($name, "cron");
   db_query("UPDATE crons SET timestamp = ". time() ." WHERE module = '$name'");
 }
 
diff --git a/modules/cvs.module b/modules/cvs.module
index 701a377ee294..71e7b5ce4a80 100644
--- a/modules/cvs.module
+++ b/modules/cvs.module
@@ -1,9 +1,5 @@
 <?php
 
-$module = array("cron" => "cvs_cron",
-                "conf" => "cvs_conf",
-                "page" => "cvs_page");
-
 function cvs_cron() {
   $result = db_query("SELECT * FROM cvs WHERE status = '0' ORDER BY timestamp DESC LIMIT 50");
 
diff --git a/modules/diary.module b/modules/diary.module
index a3b757d7927a..ef7d81cca5e8 100644
--- a/modules/diary.module
+++ b/modules/diary.module
@@ -1,15 +1,5 @@
 <?php
 
-$module = array("find" => "diary_find",
-                "help" => "diary_help",
-                "menu" => "diary_menu",
-                "page"  => "diary_page",
-                "admin" => "diary_admin",
-                "block" => "diary_block",
-                "export" => "diary_export");
-
-include_once "includes/common.inc";
-
 function diary_find($keys) {
   global $user;
   $find = array();
diff --git a/modules/drupal.module b/modules/drupal.module
index 293c3a9bc4a5..eb9d0bd92a3b 100644
--- a/modules/drupal.module
+++ b/modules/drupal.module
@@ -1,7 +1,5 @@
 <?php
 
-$module = array("page" => "drupal_page");
-
 function drupal_page() {
   global $theme, $user;
 
diff --git a/modules/drupal/drupal.module b/modules/drupal/drupal.module
index 293c3a9bc4a5..eb9d0bd92a3b 100644
--- a/modules/drupal/drupal.module
+++ b/modules/drupal/drupal.module
@@ -1,7 +1,5 @@
 <?php
 
-$module = array("page" => "drupal_page");
-
 function drupal_page() {
   global $theme, $user;
 
diff --git a/modules/forum.module b/modules/forum.module
index 0e7c6cce734c..a414a47a0db5 100644
--- a/modules/forum.module
+++ b/modules/forum.module
@@ -1,8 +1,5 @@
 <?php
 
-$module = array("page" => "forum_page",
-                "admin" => "forum_admin");
-
 $format = array(0 => HTML, 1 => PHP, 2 => text);
 
 function forum_status() {
diff --git a/modules/forum/forum.module b/modules/forum/forum.module
index 0e7c6cce734c..a414a47a0db5 100644
--- a/modules/forum/forum.module
+++ b/modules/forum/forum.module
@@ -1,8 +1,5 @@
 <?php
 
-$module = array("page" => "forum_page",
-                "admin" => "forum_admin");
-
 $format = array(0 => HTML, 1 => PHP, 2 => text);
 
 function forum_status() {
diff --git a/modules/headline.module b/modules/headline.module
index ac216c53c45b..91425e3fb3ce 100644
--- a/modules/headline.module
+++ b/modules/headline.module
@@ -1,13 +1,5 @@
 <?php
 
-$module = array("page"  => "headline_page",
-                "cron"  => "headline_cron",
-                "help"  => "headline_help",
-                "block" => "headline_block",
-                "admin" => "headline_admin",
-                "export" => "headline_export");
-
-include_once "includes/common.inc";
 include_once "modules/backend.class";
 
 function headline_blocks() {
@@ -151,8 +143,7 @@ function headline_admin_add() {
 }
 
 function headline_admin_rehash() {
-  global $repository;
-  module_rehash_blocks("headline", $repository["headline"]);
+  module_rehash_blocks("headline");
 }
 
 function headline_admin() {
diff --git a/modules/headlineRSS10.module b/modules/headlineRSS10.module
index f24b31e42f13..00940fa544e2 100644
--- a/modules/headlineRSS10.module
+++ b/modules/headlineRSS10.module
@@ -1,12 +1,5 @@
 <?php
 
-// RSS 1.0 headline exporter (v0.1)
-//
-// Kristjan Jansen -- kika@sloleht.ee
-
-$module = array("export" => "headlineRSS10_export");
-
-include_once "includes/common.inc";
 include_once "modules/backend.class";
 
 function headlineRSS10_export($uri) {
diff --git a/modules/help.module b/modules/help.module
index 9aae72a3c4e1..8d92d961181a 100644
--- a/modules/help.module
+++ b/modules/help.module
@@ -1,11 +1,10 @@
 <?php
 
-$module = array("admin" => "help_admin");
-
-function help_module($name, $module) {
-  print "<H2><A NAME=\"$name\">". ucfirst($name) ." module</A></H2>";
-  if ($module["help"]) $module["help"]();
-  else print "<I>No documentation available for module '$name'.</I>";
+function help_module($name) {
+  if (module_hook($name, "help")) {
+    print "<H2><A NAME=\"$name\">". ucfirst($name) ." module</A></H2>";
+    print module_invoke($name, "help");
+  }
 }
 
 function help_admin() {
diff --git a/modules/help/help.module b/modules/help/help.module
index 9aae72a3c4e1..8d92d961181a 100644
--- a/modules/help/help.module
+++ b/modules/help/help.module
@@ -1,11 +1,10 @@
 <?php
 
-$module = array("admin" => "help_admin");
-
-function help_module($name, $module) {
-  print "<H2><A NAME=\"$name\">". ucfirst($name) ." module</A></H2>";
-  if ($module["help"]) $module["help"]();
-  else print "<I>No documentation available for module '$name'.</I>";
+function help_module($name) {
+  if (module_hook($name, "help")) {
+    print "<H2><A NAME=\"$name\">". ucfirst($name) ." module</A></H2>";
+    print module_invoke($name, "help");
+  }
 }
 
 function help_admin() {
diff --git a/modules/locale.module b/modules/locale.module
index 1ddde9a7c82a..deb802b2977f 100644
--- a/modules/locale.module
+++ b/modules/locale.module
@@ -1,9 +1,5 @@
 <?php
 
-$module = array("help" => "locale_help",
-                "admin" => "locale_admin",
-                "locale" => "locale_locale");
-
 function locale_help() {
  ?>
   <P>Normally programs are written and documented in English, and use English to interact with users.  This is true for a great deal of websites.  However, most people are less comfortable with English than with their own native language, and would prefer to use their mother tongue as much as possible.  Many people love see their website showing a lot less of English, and far more of their own language.</P>
diff --git a/modules/locale/locale.module b/modules/locale/locale.module
index 1ddde9a7c82a..deb802b2977f 100644
--- a/modules/locale/locale.module
+++ b/modules/locale/locale.module
@@ -1,9 +1,5 @@
 <?php
 
-$module = array("help" => "locale_help",
-                "admin" => "locale_admin",
-                "locale" => "locale_locale");
-
 function locale_help() {
  ?>
   <P>Normally programs are written and documented in English, and use English to interact with users.  This is true for a great deal of websites.  However, most people are less comfortable with English than with their own native language, and would prefer to use their mother tongue as much as possible.  Many people love see their website showing a lot less of English, and far more of their own language.</P>
diff --git a/modules/moderate.module b/modules/moderate.module
index 5ce6d6d3a31a..821a588ca24d 100644
--- a/modules/moderate.module
+++ b/modules/moderate.module
@@ -1,7 +1,5 @@
 <?php
 
-$module = array("admin" => "moderate_admin");
-
 function moderate_comment_access($cid) {
   global $user;
   return db_fetch_object(db_query("SELECT n.moderate FROM comments c LEFT JOIN node n ON c.lid = n.nid WHERE c.cid = '". check_input($cid) ."' AND n.moderate LIKE '%$user->userid%'"));
@@ -30,29 +28,25 @@ function moderate_overview($query = array()) {
   return $output;
 }
 
-function moderate_node_edit($id) {
+function moderate_node($edit, $name) {
   global $user;
 
-  $node = node_get_array("nid", $id);
+  $node = node_get_array("nid", $edit[nid]);
   if ($node && strstr($node[moderate], $user->userid)) {
-    return node_form($node);
+    $edit[type] = $node[type];
+    return node_invoke($edit, $name);
   }
   else {
-    return "access denied";
+    return status(t("access denied"));
   }
 }
 
-function moderate_node_save($edit) {
-  global $user;
+function moderate_node_edit($edit) {
+  return moderate_node($edit, "form");
+}
 
-  $node = node_get_array("nid", $edit[nid]);
-  if ($node && strstr($node[moderate], $user->userid)) {
-    $edit[type] = $node[type];
-    return node_invoke($edit, "save");
-  }
-  else {
-    return "access denied";
-  }
+function moderate_node_save($edit) {
+  return moderate_node($edit, "save");
 }
 
 function moderate_comment_edit($id) {
@@ -92,7 +86,10 @@ function moderate_admin() {
     default:
       switch ($op) {
         case "edit":
-          print moderate_node_edit($id);
+          print moderate_node_edit(node_get_array("nid", $id));
+          break;
+        case t("Preview"):
+          print moderate_node_edit($edit);
           break;
         case t("Submit"):
           print status(moderate_node_save($edit));
diff --git a/modules/module.module b/modules/module.module
index e4140ce22b3e..f118327705d6 100644
--- a/modules/module.module
+++ b/modules/module.module
@@ -1,8 +1,5 @@
 <?php
 
-$module = array("help" => "module_help",
-                "admin" => "module_admin");
-
 function module_help() {
  ?>
   The module administration page provide you a list of all available modules.  Moreover, it allows you to "rehash" modules.  Whenever you install a new module or when an existing module has been changed or updated, it requires "rehashing": when you rehash a module, the module is registered to the engine and properly initialized.
@@ -10,34 +7,24 @@ function module_help() {
 }
 
 function module_admin_rehash() {
-  global $repository;
-
   $result = db_query("SELECT * FROM modules");
   while ($module = db_fetch_object($result)) {
     module_rehash($module->name);
   }
 
-  foreach ($repository as $name=>$module) {
+  foreach (module_list() as $name) {
     module_rehash($name);
   }
 }
 
-function module_admin_display() {
-  global $output;
-
-  function module_row($name, $module) {
-    global $output;
-
-    $view = ($module["page"]) ? "<A HREF=\"module.php?mod=$name\">view</A>" : "&nbsp;";
-    $admin = ($module["admin"]) ? "<A HREF=\"admin.php?mod=$name\">admin</A>" : "&nbsp;";
-    $output .= " <TR><TD>$name</TD><TD>$view</TD><TD>$admin</TD><TD><A HREF=\"admin.php?mod=module&op=rehash&name=$name\">rehash</A></TD></TR>\n";
-  }
-
+function module_admin_overview() {
   $output .= "<FORM ACTION=\"admin.php?mod=module\" METHOD=\"post\">\n";
   $output .= "<TABLE BORDER=\"1\" CELLPADDING=\"2\" CELLSPACING=\"2\">\n";
   $output .= " <TR><TH>module</TH><TH COLSPAN=\"3\">operations</TH></TR>\n";
 
-  module_iterate("module_row");
+  foreach (module_list() as $name) {
+    $output .= " <TR><TD>$name</TD><TD>". (module_hook($name, "page") ? "<A HREF=\"module.php?mod=$name\">view</A>" : "&nbsp;") ."</TD><TD>". (module_hook($name, "admin") ? "<A HREF=\"admin.php?mod=$name\">admin</A>" : "&nbsp;") ."</TD><TD><A HREF=\"admin.php?mod=module&op=rehash&name=$name\">rehash</A></TD></TR>\n";
+  }
 
   $output .= "</TABLE>\n";
   $output .= "<INPUT NAME=\"op\" TYPE=\"submit\" VALUE=\"Rehash modules\">\n";
@@ -56,14 +43,14 @@ function module_admin() {
       break;
     case "rehash":
       module_rehash($name);
-      module_admin_display();
+      module_admin_overview();
       break;
     case "Rehash modules":
       module_admin_rehash();
-      module_admin_display();
+      module_admin_overview();
       break;
     default:
-      module_admin_display();
+      module_admin_overview();
   }
 }
 
diff --git a/modules/node.module b/modules/node.module
index bdc4b30d60e2..cff8e636d305 100644
--- a/modules/node.module
+++ b/modules/node.module
@@ -1,6 +1,15 @@
 <?php
 
-$module = array("admin" => "node_admin");
+class Node {
+  function Node($node) {
+    global $user;
+    $this->userid = $node[userid] ? $node[userid] : $user->userid;
+    $this->title = $node[title];
+    $this->timestamp = $node[timestamp] ? $node[timestamp] : time();
+    $this->cid = $node[cid];
+    $this->tid = $node[tid];
+  }
+}
 
 function node_overview($query = array()) {
   global $user;
diff --git a/modules/node/node.module b/modules/node/node.module
index bdc4b30d60e2..cff8e636d305 100644
--- a/modules/node/node.module
+++ b/modules/node/node.module
@@ -1,6 +1,15 @@
 <?php
 
-$module = array("admin" => "node_admin");
+class Node {
+  function Node($node) {
+    global $user;
+    $this->userid = $node[userid] ? $node[userid] : $user->userid;
+    $this->title = $node[title];
+    $this->timestamp = $node[timestamp] ? $node[timestamp] : time();
+    $this->cid = $node[cid];
+    $this->tid = $node[tid];
+  }
+}
 
 function node_overview($query = array()) {
   global $user;
diff --git a/modules/page.module b/modules/page.module
index 65379b729f99..03ca6165fe46 100644
--- a/modules/page.module
+++ b/modules/page.module
@@ -1,7 +1,5 @@
 <?php
 
-$module = array("admin" => "page_admin");
-
 $format = array(0 => HTML, 1 => PHP, 2 => text);
 
 function page_view($node, $main = 0) {
diff --git a/modules/page/page.module b/modules/page/page.module
index 65379b729f99..03ca6165fe46 100644
--- a/modules/page/page.module
+++ b/modules/page/page.module
@@ -1,7 +1,5 @@
 <?php
 
-$module = array("admin" => "page_admin");
-
 $format = array(0 => HTML, 1 => PHP, 2 => text);
 
 function page_view($node, $main = 0) {
diff --git a/modules/queue.module b/modules/queue.module
index 31087d5f3314..69c73878436f 100644
--- a/modules/queue.module
+++ b/modules/queue.module
@@ -10,9 +10,6 @@
                           "post it (+1)" => "+ 1",
                           "dump it (-1)" => "- 1");
 
-$module = array("menu" => "queue_menu",
-                "page" => "queue_page");
-
 function queue_menu() {
   return array("<A HREF=\"module.php?mod=queue\">". t("moderation queue") ."</A> (<FONT COLOR=\"red\">". queue_count() ."</FONT>)");
 }
diff --git a/modules/rating.module b/modules/rating.module
index c5e665592418..cc6b02caf744 100644
--- a/modules/rating.module
+++ b/modules/rating.module
@@ -1,10 +1,5 @@
 <?php
 
-$module = array("cron" => "rating_cron",
-                "help" => "rating_help",
-                "page" => "rating_page",
-                "block" => "rating_block");
-
 function rating_cron() {
   $r1 = db_query("SELECT id FROM users ORDER BY rating DESC");
   while ($account = db_fetch_object($r1)) {
diff --git a/modules/settings.module b/modules/settings.module
index 6952bbae6e41..acb5af2cd2dd 100644
--- a/modules/settings.module
+++ b/modules/settings.module
@@ -1,7 +1,5 @@
 <?php
 
-$module = array("admin" => "settings_admin");
-
 function settings_conf() {
   global $conf, $cmodes, $corder, $themes;
 
@@ -66,12 +64,12 @@ function settings_default() {
   return "all settings have been reset.";
 }
 
-function settings_module($name, $module) {
+function settings_module($name) {
   global $settings;
 
-  if ($module["conf"]) {
+  if (module_hook($name, "conf")) {
     $settings .= "<H3>". ucfirst($name) ." module</H3>\n";
-    $settings .= $module["conf"]();
+    $settings .= module_invoke($name, "conf");
     $settings .= "<HR>\n";
   }
 }
diff --git a/modules/story.module b/modules/story.module
index c2dff470919d..58469aa123ac 100644
--- a/modules/story.module
+++ b/modules/story.module
@@ -1,22 +1,10 @@
 <?php
 
-$module = array("help" => "story_help",
-                "find" => "story_find",
-                "user" => "story_user",
-                "queue" => "story_queue",
-                "admin" => "story_admin",
-                "block" => "story_block");
-
 class Story {
   function Story($story) {
-    global $user;
-    $this->userid = $story[userid] ? $story[userid] : $user->userid;
-    $this->title = $story[title];
+    $this = new Node($story);
     $this->abstract = $story[abstract];
     $this->body = $story[body];
-    $this->timestamp = $story[timestamp] ? $story[timestamp] : time();
-    $this->cid = $story[cid];
-    $this->tid = $story[tid];
   }
 }
 
diff --git a/modules/story/story.module b/modules/story/story.module
index c2dff470919d..58469aa123ac 100644
--- a/modules/story/story.module
+++ b/modules/story/story.module
@@ -1,22 +1,10 @@
 <?php
 
-$module = array("help" => "story_help",
-                "find" => "story_find",
-                "user" => "story_user",
-                "queue" => "story_queue",
-                "admin" => "story_admin",
-                "block" => "story_block");
-
 class Story {
   function Story($story) {
-    global $user;
-    $this->userid = $story[userid] ? $story[userid] : $user->userid;
-    $this->title = $story[title];
+    $this = new Node($story);
     $this->abstract = $story[abstract];
     $this->body = $story[body];
-    $this->timestamp = $story[timestamp] ? $story[timestamp] : time();
-    $this->cid = $story[cid];
-    $this->tid = $story[tid];
   }
 }
 
diff --git a/modules/structure.module b/modules/structure.module
index 2f5138431b8b..f51bc7f5e7c5 100644
--- a/modules/structure.module
+++ b/modules/structure.module
@@ -1,10 +1,8 @@
 <?php
 
-$module = array("admin" => "structure_admin");
-
-function content_types($name, $module) {
+function content_types($name) {
   global $types;
-  if ($module[type]) $types[$name] = $name;
+  if (function_exists($name ."_status")) $types[$name] = $name;
 }
 
 function category_form($edit = array()) {
diff --git a/modules/watchdog.module b/modules/watchdog.module
index 23e803e62461..a3d04b36dc25 100644
--- a/modules/watchdog.module
+++ b/modules/watchdog.module
@@ -1,9 +1,5 @@
 <?php
 
-$module = array("help" => "watchdog_help",
-                "cron" => "watchdog_cron",
-                "admin" => "watchdog_admin");
-
 function watchdog_help() {
  ?>
   <P>The watchdog module monitors your website, captures system events in a log and records them to be reviewed by an authorized individual at a later time.  The watchdog log is simply a list of events recorded during operation and contains usage data, performance data, errors, warnings and operational information.  It is vital to check the watchdog report on a regular basis as it is often the only way to tell what is going on.</P>
diff --git a/modules/watchdog/watchdog.module b/modules/watchdog/watchdog.module
index 23e803e62461..a3d04b36dc25 100644
--- a/modules/watchdog/watchdog.module
+++ b/modules/watchdog/watchdog.module
@@ -1,9 +1,5 @@
 <?php
 
-$module = array("help" => "watchdog_help",
-                "cron" => "watchdog_cron",
-                "admin" => "watchdog_admin");
-
 function watchdog_help() {
  ?>
   <P>The watchdog module monitors your website, captures system events in a log and records them to be reviewed by an authorized individual at a later time.  The watchdog log is simply a list of events recorded during operation and contains usage data, performance data, errors, warnings and operational information.  It is vital to check the watchdog report on a regular basis as it is often the only way to tell what is going on.</P>
diff --git a/search.php b/search.php
index 4a7831babece..60791e62ecf3 100644
--- a/search.php
+++ b/search.php
@@ -2,9 +2,9 @@
 
 include_once "includes/common.inc";
 
-function find_module($name, $module) {
+function find_module($name) {
   global $options, $type;
-  if ($module["find"]) $options .= "<OPTION VALUE=\"$name\"". ($name == $type ? " SELECTED" : "") .">$name</OPTION>\n";
+  if (module_hook($name, "find")) $options .= "<OPTION VALUE=\"$name\"". ($name == $type ? " SELECTED" : "") .">$name</OPTION>\n";
 }
 
 module_iterate("find_module");
diff --git a/submit.php b/submit.php
index 123c4b1e6ba7..53af0e27a5d6 100644
--- a/submit.php
+++ b/submit.php
@@ -6,7 +6,7 @@
 
 if ($user->id) {
   if ($mod) {
-    module_execute($mod, "user");
+    module_invoke($mod, "user");
   }
   else {
     $result = db_query("SELECT * FROM category");
-- 
GitLab