Blog Archive

Thursday 8 November 2012

Creating an advanced module in FUEL CMS v1

Creating an advanced module in FUEL CMS v1 (beta) has become rather easier, since this release provides some “scaffolding” from the PHP CLI which creates the core files you will need to begin your project.

If it’s not clear what an “advanced module” is, it is a mini application folder under the fuel/modules path. If you never intend to repeat the simple modules you create as per Codeigniter, then you might not find the extra effort worthwhile. If you have a mind to portability, or just like tidy modularity, then trying an advanced module is time well spent.

For this tutorial, I’m going to take a well known library from Codeigniter, and ease it into a FUEL CMS advanced module. The library is Ion Auth, an authentication application that creates a secure login with the further ability to associate logins with groups. I’m going to use that library’s users table as my “members” table, but keep groups more or less the same.

Step one

The first task is to decide what to name the module. This is important, as you will not want any clashes with sub controller names, which will cause grief later on. I chose “membership”, which means that using the Ion Auth controller methods, urls will look like “your-site/membership/login”, “your-site/membership/logout” and so on.

STEP TWO

Having decided on a name, it’s time to generate the scaffold files. You will need to use the command line, so navigate to your installation and issue a command like:

php index.php fuel/generate/advanced/ membership

This will create a folder under the fuel/modules path called “membership”, and populate it with config, controller and helper files, and much else. But, it won’t create models, as these are much more likely to be unique to any given project. So the next CLI command will create the models

php index.php fuel/generate/simple members:groups membership

That command deserves some explanation: although the path includes “simple”, the arguments, the last especially, instruct the creation of models “members” and  “groups” in the “membership” advanced module folder. It is possible to chain more model names together using a semicolon as a separator, if you need to. The database tables “members” and “groups” also get created (provided you have set up a database connection already), but only in a rudimentary fashion.

So, after that you should have a “members_model.php” and “groups_model.php” in the modules /models subfolder.The models are quite basic, but functional. They can be made more sophisticated, as per the tutorial here.

Step tHREE

Next we will configure the module to play nicely in FUEL’s admin.

The previous CLI commands will have added the “membership” module to the FUEL CMS admin for you, with a link to an admin url “membership”. If you follow this link, it will be horribly broken. That’s to be expected. The admin doesn’t know what to do with “/membership”. Open the module’s routes file (membership_routes.php) and add this:

   1:  $route[FUEL_ROUTE.'membership'] = 'membership';
   2:   
   3:  $membership_controllers = array('members', 'groups');
   4:   
   5:  foreach($membership_controllers as $c)
   6:  {
   7:    $route[FUEL_ROUTE.$route[FUEL_ROUTE.'membership'].'/'.$c] = FUEL_FOLDER.'/module';
   8:    $route[FUEL_ROUTE.$route[FUEL_ROUTE.'membership'].'/'.$c.'/(.*)'] = FUEL_FOLDER.'/module/$1';
   9:  }



This is going to map 2 new links we will be creating, “members” and “groups”, on to FUEL’s Module controller class. Doing that will hook into the CRUD facilities of the admin. Note that we don’t need to actually create controllers for “members” and “groups”,  we are just mapping routes on to a class that is itself a controller, and will do all the admin stuff for us.


STEP FOUR


To create the links we need to edit the module’s config file (config.php)


   1:  $config['nav']['membership'] = array(
   2:    'membership/members' => 'Members',
   3:    'membership/groups' => 'Groups'
   4:  );
   5:  // tables for membership
   6:  $config['tables']['members'] = 'members';
   7:  $config['tables']['groups'] = 'groups';



Now when we follow these new links in the admin, there is a new error: “unable to locate the file…”. The model’s are missing! This is because we need to do some more configuring, this time in “membership_fuel_modules.php”. We need to specify where the models are:


   1:  $config['modules']['members'] = array(
   2:    'model_location' => 'membership',
   3:    'module_name' => 'Members',
   4:    'module_uri' => 'membership/members',
   5:    'model_name' => 'members_model',
   6:    'nav_selected' => 'membership/members',
   7:  );
   8:  $config['modules']['groups'] = array(
   9:    'model_location' => 'membership',
  10:    'module_name' => 'Member Groups',
  11:    'module_uri' => 'membership/groups',
  12:    'model_name' => 'groups_model',
  13:    'nav_selected' => 'membership/groups',
  14:  );



Actually, we do a lot more here than specify the model location, but it’s all pretty obvious.


At this point you should be able to use the admin navigation links (members, groups) and see list & create pages served up by FUEL’s Module class. Sweet.


STEP FIVE


Return to your SQL editor! Although the scaffold process created database tables, they need to be more specific. For the “members” table I repurposed the “users” table from the Ion Auth library. Likewise, the “groups” table is the same as the one in that package.


STEP SIX


The last step requires adding and configuring the Ion Auth library. The files simply go in the module’s folder, just as they would if they were in the application directory.


I repurposed the scaffolded membership controller to be the equivalent of the auth controller supplied with the library. Note however that the generated class is intended to be an admin compatible one, based on Module. For a front-end facing controller, we can just use CI_Controller, MY_Controller or whatever. It’s also important to note that some of the loading methods need altering: eg instead of regular

$this->load->library('ion_auth');



we need to use the one specifically for modules:

$this->load->module_library('membership', 'ion_auth');



which explicitly tells FUEL what module to look in (eg membership/libraries in this instance).


There are various paths that need to be edited from the original Ion Auth code: the controller path “auth” is used as a target for redirect() quite often, and the views all use “auth” in their actions. We can make use of a constant found in “membership_constants.php”, and substitute MEMBERSHIP_FOLDER. Of course if you elected to call you module “auth” in the first place, there would be no need.


The Ion Auth library has its own config file, and we can assign the tables variables to the database names we are using  eg

$config['tables']['users'] = 'members';



By visiting /membership/login from the front end, we should now see the Ion Auth views, and a functioning authentication system.


AFTERWORD


Although most aspects of this demonstration are working, there are lots of holes. Ion Auth uses some crafty hashing to create its passwords, so although you can create users from /membership/create_user (if you are logged in as the ion Auth admin) you will not create them properly from the FUEL admin. This is because the hashing process is not hooked in to the members_model.


Additionally there are other fields on display by default that should either be hidden, or be a different type.


Also, the groups table isn’t even used by the members model! However, v1 of FUEL CMS introduces an ingenious “has_many” relationship, and it is possible to add a multi-select field to the members_model so that group associations can be stored in the fuel_relationships table, without fiddling around with separate lookups.


These deficiencies are rectifiable though, and I will leave these to the reader to solve.

2 comments:

  1. This was awesome for adding Ion_auth to the CMS, but has no information on how to make membership accessible from the front end which I'm trying to figure out now.
    I've been searching for steps to create a fully functional advanced module and yours is the closest I've found.

    My biggest problem I suppose is my inexperience with Codeigniter.

    I'm able to get the Ion_auth library accessible in the Advanced module to use it's features. And I'm able to get Ion_auth settings working properly in the CMS, but I want to make the module complete where /membership/login and membership/logout and whatever other features I need get accessed easily and with minimal fuss.

    Any thoughts? :)

    ReplyDelete
    Replies
    1. Hi Chris,

      the CLI "scaffolding" should have created a membership controller in the module. This is the controller that will deal with urls like yoursite/membership. So the methods in the Ion auth controller can be moved wholesale (give or take) to this controller (the tutorial mentions this briefly in step 6). So for example logout() will be the method in the membership controller that responds to membership/logout. Probably easier than you were expecting!

      The routing for FUEL works like this (I think) - for a given url it looks in the application controllers (as per CI), or also the view folder (the "opt-in" aspect), then in the "advanced" modules folder. Check the routes.php file in the application/config folder there is a line at the end include(MODULES_PATH.'/fuel/config/fuel_routes.php').

      Truth be told this was a project I thought I might need myself, but haven't really used it in anger, and there could be a lot more done with it. It would be great if there were a repository of FUEL CMS advanced modules somewhere (apart from the few FUEL ones on GitHub), then I would be keen to add this one. In fact, using the regular modules often suffices I've found!

      Delete

My top artists