views:

58

answers:

4

Hi!

I'm writing a CMS, but I've got a problem. I have a mysql table called modules. Modules are similar to Wordpress' plug-ins, or Drupal Modules. Some modules require functions of other modules. I'm now writing the part which includes the modules. Here's my code:

//Load modules
$res_modules = mysql_query("SELECT * FROM ".$db_prefix."modules WHERE enabled=1");
echo mysql_error();
while($row_modules = mysql_fetch_array($res_modules))
{
    //Check if module exists
    if(file_exists("MODULES/".$row_modules["name"]."/module.php"))
    {
     require_once("MODULES/".$row_modules["name"]."/module.php");//Include module
    }
    else//Module does not exists...
    {
     //...so deactivate it
     mysql_query("UPDATE ".$db_prefix."modules SET enabled=0 WHERE name='".$row_modules["name"]."'");
    }
}

Does someone knows an algorithm that allows some modules (those who require other modules) to be included after other modules? The actual big problem is, that modules can also require each other's functions (module x can use functions of module y and vice versa (which could result in a stack overflow :P)). The modules which require other modules have an array called $req_modules in their module.php file. Example:

$req_modules = array("page", "comments");

Thanks!

+1  A: 

You can either store in the DB which other modules the module requires and then include them within your while loop or simply include_once() or require_once() the modules at the top of your module.php page - then when a module is loaded it will attempt to include the required modules that it needs.

Jacob Wyke
You are a genius.
Time Machine
A: 

I solved this in mine by having two constructor functions, with the second being an (optional) constructor that is called after the initial modules (and main constructors) load. So if a module relies on features from another it should be placed in the secondary constructor, rather than the main. It's an optional part though so it is only used if needed.

Meep3D
Does this also work if the modules require each other?
Time Machine
+1  A: 

First of all, are there any compelling reasons you're creating your own CMS? There are literally hundreds of free, open-source, and commercial alternatives out there that have already solved the problems you're going to be facing writing your own.

As for module prerequisites, you have a couple options. I don't see why your current mechanism doesn't work. Simply add a check after the require_once('MODULES/...') line, something like this:

function include_module($module_name) {
 static $already_included_modules;
 if (!isset($already_included_modules))
  $already_included_modules = array();
 require_once('MODULES/' . $row['name'] . '/module.php');
 $class = 'Module_' . $row['name'];
 $module_instance = new $class;
 if (!empty($class->req_modules)) {
  foreach ($class->req_modules as $req_module) {
   if (isset($already_included_modules[$req_module])) continue;
   include_module($req_module);
  }
 }
 $already_included_modules[$module_name] = true;
}

A possibly more versatile solution would be to store the module dependencies in your database and resolve them before starting to load modules.

pix0r
+1  A: 

You shouldn't care about which module is included first. You should only care about whether the required modules are active or not. You can ignore the loading order by not running any code directly inside your module.php. Put all of your code in functions or class methods and then have your cms call a module init function ( like a main function in a program ) that is defined by each module. The cms should call these functions only after all of the code is loaded.

Mihai Secasiu
Thanks. I didn't like classes before. Now I use them for about two hours, and yeh yeh I like that
Time Machine