TheDrunkenEpic

Hello, I'm Wilhelm, a PHP developer, and this is my little corner of the internet where I can discuss things that interest me and, hopefully, you too. :-)


Currently Reading:

16Jun 2007

Building MyTopix Modules

With MyTopix becoming more and more popular in recent months I think it's about time I started pumping out some tutorials so you all can make your own modifications and features. I've always thought that people learned more through example rather than reading long and drawn out technical documentation, so let's just jump right into the system and learn what modules are, how they work and how we can create new ones.

Understanding The Basics

In order to create a new module, one must understand how MyTopix handles said modules. What's a module? Well, in this instance a module could be defined as the individual screens you view when browsing the MyTopix interface. For example, the user registration area of MyTopix is referred to as the register module. The same goes for your personal control panel, the private messaging system and so on. Each of these sections all have their very own modules.

To add a new module to MyTopix, you need to do two simple things. First, you need the actual module itself, which is a PHP file. Second, you need to tell the system that the module actually exists by registering it. But, before we get into that, let's discuss what a module really is.

What Makes a Module?

Since MyTopix is written using simple object oriented principles, all modules exist as objects. All module objects are given the name ModuleObject. Since modules are only ever executed one per user request, there are never any naming conflicts, so giving all module objects the same name is never really an issue.

Below, you will find an example of a module object in its most simplest form. I will try my best to explain how it works in Layman's terms, but I won't go into too much detail about the object oriented aspects of the code as it falls out of this article's scope.

class ModuleObject extends MasterObject
{
    var $_message;

    function ModuleObject(& $module, & $config, $cache)
    {
        $this->MasterObject($module, $config, $cache);

        $this->_message = 'Hello World!';
    }

    function execute()
    {
        return $this->_message;
    }
}
Class Naming Conventions

You can see here the class ModuleObject being declared and extending its parent class MasterObject. The class MasterObject is just that, a master object, because it contains all the core functions the system will ever need to get its modules running properly. For instance, it contains the UserHandler, which is an object responsible for authenticating user sessions and pulling their account data.MasterObject also contains the database abstraction layer that allows modules to interact with the specified database.

class ModuleObject extends MasterObject
Defining Instance Variables

Next, we have an example of an instance variable, also called an object's property. Instance variables, depending on their types, are usually used to define an object's attributes. In the example above, our particular module object has a message attribute that will only be used within said object.

var $_message;
Constructors

Moving on, we have the module object's constructor. A constructor is basically a method that is automatically called once you instantiate (or run) an object. It's purpose is to, more or less, prepare the object for use. In MyTopix, all constructors must have the same name as the objects they reside in.

function ModuleObject(& $module, & $config, $cache)

You can also see 3 parameters that are passed into the constructor. These are very important and essential if you want your modules to work properly, or at all.

The first parameter, $module, is just the system name of the requested module. For example, if you're registering a new account, the name of the module being executed is register.

The second parameter, $config, is the system configuration array. This contains the values for all the system settings which include paths to special directories, configuration options for user avatars, etc.

The third and final parameter, $cache, contains which cache groups are assigned to the requested module. Just as with every other system out there, cache can be considered a storage area that contains frequently used data. For instance, all forum settings are cached as well as skin, language and emoticon information. We place all these cache groups in a single table within the database, so we can call upon them all using a single query rather than a complex query for each table we need to pull data from. We'll discuss MyTopix's version of caching in greater detail in a future article.

You may also notice the following line right below where we declared the constructor:

$this->MasterObject($module, $config, $cache);

On this line, we are instantiating the parent class MasterObject and routing all those previously mentioned parameters to it. Once we get to this step, the system executes the MasterObject constructor, which, in turn, loads all the core library objects.

Finally, you will notice that we're giving our message instance variable a default value of 'Hello World!'. It is good practice to assign default values to ALL your declared instance variables within the module object's constructor.

$this->_message = 'Hello World!';
The Boot Method

Every module needs a boot method. As the final step in the system's initialization process, the boot method is typically the very last thing to execute. All boot methods for modules are aptly entitled execute. This is where all the magic happens for your module. It is within this method where you place all your custom code and calls to other subroutines. In our little example, the boot method simply returns a message that every code monkey should be familiar with:

function execute()
{
    return $this->_message;
}

You might want to note that all methods, excluding the constructor, should return something, anything. So, when in doubt, just add return true; to the very end of all your methods.

Adding a New Module

Now that we have a basic idea of how modules are handled within MyTopix we can begin learning about how to add them to the system. Remember, there are 2 steps that we need to take in order to implement a new module.

Implementing the Module's File

This is probably the simplest step. All it involves is dropping your new module file in the appropriate directory. For this article, let's just save our basic object in a file named test.mod.php to the modules directory, which can be found directly beneath your MyTopix root directory. If you are working with a hosted MyTopix installation, you'll need to FTP the file to the corresponding directory after saving it locally.

Registering the Module

This step may seem a bit confusing to some, so I'll try and tone it down a bit. In order for MyTopix to actually see your new module, you need to register it within the system. In order to do so, you will need to modify a source file. Don't worry, it's easier than you think.

Within your MyTopix installation, navigate to the config directory that resides directly beneath the system's root. You see a listing of files, one of which is named pub_modules.php; short for 'public modules'. Open this file and take a peak inside. You will see the following:

$modules = array();

//MODULE NAMES:        CACHE GROUPS:

$modules['active']   = array('forums');
... 
more modules 
...
$modules['calendar'] = array('emoticons', 'filter', 'titles');

As you can see, the system's module registry is a simple 2-dimensional array containing the system names of modules and corresponding cache groups.

We want the system to see our test.mod.php file, so we are going to add the following line directly after the very last entry of the list.

$modules['test'] = array();

Note that the name of our entry is exactly the same as the file name of our module, test.mod.php. This is important because if you misspell the entry, MyTopix will attempt to open a file that does not exist, thus resulting in the system going banana sandwiches. We don't want that, so be careful.

When we are done, the registry should now look like:

$modules = array();

//MODULE NAMES:        CACHE GROUPS:

$modules['active']   = array('forums');
... 
more modules 
...
$modules['calendar'] = array('emoticons', 'filter', 'titles');
$modules['test']     = array();

Save the file and place it in the appropriate directory, overwriting the old version.

The Moment of Truth

Now that we finished all these steps, we can finally call this module and see the result of all our hard work. In MyTopix, to call a module, you must use the following format:

http://www.mysite.com/forum/index.php?a=module_name
or, in this case,
http://www.mysite.com/forum/index.php?a=test

If you see 'Hello World!' printed at the top of the screen, you can consider your efforts a success!

In Closing ...

In this installment, you learned what modules are how they operate within the system. You also learned how to create your own custom modules and implement them to add new functionality to your MyTopix installation. Unfortunately, without knowing more about MyTopix's core functionality, your early modules probably won't be doing much. We plan on addressing this issue in the coming weeks.

In our next article, I will teach you how to create your very own basic RSS module and, in doing so, introduce you to some of the most widely used objects within MyTopix. Sort of a bonus for some, I suppose, considering the fact that RSS functionality is one of the most requested feature enhancements for the system.

Well, I hope you all enjoyed this article and were able to get something out of it. Thanks and stay tuned for more!


Your Commentary:

Nice read even though I'd probably have to read it about 10 more times to really understand what I'm doing. But that's just my inability to process what I'm reading while I'm reading it. :P

Looking forward to the next article in the MyTopix series!

Roguefoxx spoke the truth on June 16th at 8:55 am #

Thanks for posting Dan, I'm looking forward to the rest of the series as well.

Scott spoke the truth on June 16th at 9:14 am #

No problem, guys. There are lots more to come.

Wilhelm Murdoch spoke the truth on June 16th at 2:44 pm #

This is really cool, I'm really looking forward to the rest, as I've always wanted to develop MT furthur, but I just don't have a clue as to how =/

I'm sure this series of posts will shed some light :)

Thanks

JB

Beaner spoke the truth on June 20th at 2:35 am #

Thanks, Beaners, I appreciate the kind words.

Wilhelm Murdoch spoke the truth on June 20th at 11:12 am #

albocchi

elnoccrolch spoke the truth on September 23rd at 12:38 pm #

[*comment35.txt*] qppvw

qlsuh spoke the truth on October 1st at 11:43 am #

[*comment37.txt*] pouxr

bjghy spoke the truth on October 1st at 12:55 pm #

[*comment38.txt*] nnnoy

gtqqj spoke the truth on October 1st at 1:35 pm #

[*comment40.txt*] eshyi

lhqwh spoke the truth on October 1st at 2:54 pm #

[*comment41.txt*] urktp

kfwqt spoke the truth on October 1st at 3:35 pm #

[*comment42.txt*] zlxuf

zvjdu spoke the truth on October 1st at 4:15 pm #

TrackBack: http://www.thedrunkenepic.com/home/articles/trackback/75/

Leave a Comment: