Contents |
Tutorial
TO: Forum Pool
Kaotik Index
- Basic content of a module
- using Smarty templates in a module
- Building an AJAX module
- Xoops Blocks
- Guidelines for Module Development
- Theme Development
- $_SUPER GLOBALS
- DB Operations and Classes
Basic content of a module
About this Tutorial
The first step is to download the blank module called tutorial.
Open the tutorial module and you will see it has 2 php files, 1 directory called images and inside that 1 image. This is all you need to start.
opening xoops_version.php
Now open the file xoops_version.php in an editor. You can either use a wysiwyg editor such as dreamweaver or you can use something like php Designer or Maguma Open Studio (both are free). Other options of publishers you will be able to find here: Text & programing Editors and WYSIWYG editors/ web builders
<?php // Tutorial Module // Created by kaotik $modversion['name'] = "Tutorial"; $modversion['version'] = 1.00; $modversion['description'] = "This is a tutorial module to teach how to build a simple module"; $modversion['author'] = "KaotiK"; $modversion['credits'] = "KaotiK"; $modversion['help'] = ""; $modversion['license'] = "GPL see LICENSE"; $modversion['official'] = 0; $modversion['image'] = "images/tutorial.png"; $modversion['dirname'] = "tutorial"; // Admin $modversion['hasAdmin'] = 0; // Menu $modversion['hasMain'] = 1; ?>
Step by Step
Now let's go through what this all means.
<?php // Tutorial Module // Created by kaotik
The very first line starts php, meaning that anything below this will get processed as php.
Important note: never have empty space before <?php or you will receive "headers already sent" errors.
The next 2 lines are comments stating the name of the module and who created it (in this case me).
$modversion['name'] = "Tutorial"; $modversion['version'] = 1.00; $modversion['description'] = "This is a tutorial module to teach how to build a simple module";
These 3 are self evidente, meaning as their name implies, name, version and description.
$modversion['author'] = "KaotiK"; $modversion['credits'] = "KaotiK"; $modversion['help'] = "";
Author and credits are also evidente.
Help (if used which in this case is not) should point to a file such as help.html or help.php
$modversion['license'] = "GPL see LICENSE"; $modversion['official'] = 0; $modversion['image'] = "images/tutorial.png"; $modversion['dirname'] = "tutorial";
License is the license used for the module. Keep in mind the the core uses GPL meaning that your module also falls under the GPL license. You can read more about it here. Official is whether this is an official module or not. In most cases this is set to 0. Image is the module icon you see on the module administration menu. Dirname is the directory name for the module.
// Admin $modversion['hasAdmin'] = 0; // Menu $modversion['hasMain'] = 1; ?>
hasAdmin=0 means there is no administration part to this module. Since I want the module to appear on the main menu I've set hasMain to 1. If I had set it to 0 then it wouldn't show up on main menu. If you set hasAdmin and hasMain both to 0, it will still show up on module administration allowing you to uninstall it. The last line stops php processing.
Important note: never leave empty space after ?> as this will cause unpredictable behaviour.
index.php
Using index.php
Now that we understand xoops_version, lets install our module and start work
With the module installed lets click on "tutorial" on main menu. You will see your xoops site with an empty page.
Now open index.php
<?php
// Tutorial
// Created by KaotiK
require('../../mainfile.php');
require(XOOPS_ROOT_PATH.'/header.php');
require(XOOPS_ROOT_PATH.'/footer.php');
?>
You will notice 3 new lines here. Your code should be placed inbetween the lines "...header" and "....footer". So, as a test lets write this:
<?php
// Tutorial
// Created by KaotiK
require('../../mainfile.php');
require(XOOPS_ROOT_PATH.'/header.php');
echo "Hello world!";
require(XOOPS_ROOT_PATH.'/footer.php');
?>
Now if you click "tutorial" on main menu, the words "Hello world!" will appear on your site.
Creating a List
Now lets take this a step further a create a simple list of your users.
Lets replace:
echo "Hello world!";
with:
$member_handler =& xoops_gethandler('member');
$foundusers =& $member_handler->getUsers();
foreach (array_keys($foundusers) as $j) {
echo $foundusers[$j]->getVar("uname").'
';
}
Click on tutorial on your main menu and you will now see a list of your current users. Now lets review what each line does. The first line calls a xoops handler which deals with member and assigns it to $member_handler. The second line grabs all users and places them in $foundusers as an array. Now we can loop through all the results using foreach. What foreach is doing is basicly saying "I'm going to take the whole stack and 'do something' to each 'line' ". If you wanted to see everything inside the array try this:
Warning: Only try the following code if you are using a test site with a small list of users.
$member_handler =& xoops_gethandler('member');
$foundusers =& $member_handler->getUsers();
foreach (array_keys($foundusers) as $j) {
//echo $foundusers[$j]->getVar("uname").'<br>';
print_r($foundusers[$j]);
echo '<br><br><br>';
}
You will get a big list that will look confusing but shows all variables concerning each of your users.
Moving on. Lets properly format the list and get some more info on each of your users.
First let's create a header bar for our table. As I said before, this is a simple tutorial, so I will show you the easy way, which isn't necessarily the correct way of doing it. I will however use more elaborate and professional methods in upcoming tutorials.
To avoid confusion I'm going to show the whole index.php file:
<?php
// Tutorial
// Created by KaotiK
require('../../mainfile.php');
require(XOOPS_ROOT_PATH.'/header.php');
?>
<table width="100" border="0">
<tr>
<td bgcolor="#99CC99">Name</td>
<td bgcolor="#66CC99">Email</td>
</tr>
</table>
<?php
require(XOOPS_ROOT_PATH.'/footer.php');
?>
Now click on tutorial from your main menu. You will now see a table heading saying Name and Email. Great! Lets place some info into it.
<?php
// Tutorial
// Created by KaotiK
require('../../mainfile.php');
require(XOOPS_ROOT_PATH.'/header.php');
?>
<table width="100" border="0">
<tr>
<td bgcolor="#99CC99">Name</td>
<td bgcolor="#66CC99">Email</td>
</tr>
<?php
$member_handler =& xoops_gethandler('member');
$foundusers =& $member_handler->getUsers();
foreach (array_keys($foundusers) as $j) {
echo '<tr><td>'.$foundusers[$j]->getVar("uname").'</td><td>'.$foundusers[$j]->getVar("email").'</td></tr>';
}
?>
</table>
<?php
require(XOOPS_ROOT_PATH.'/footer.php');
?>
Click on tutorial from main link and you will now see our table populated with user's name and email. Nice! However the code is very sloppy, going back and forth between php and html. Now let's do the whole thing in php:
<?php
// Tutorial
// Created by KaotiK
require('../../mainfile.php');
require(XOOPS_ROOT_PATH.'/header.php');
echo '<table width="100" border="0">
<tr>
<td bgcolor="#99CC99">Name</td>
<td bgcolor="#66CC99">Email</td>
</tr>';
$member_handler =& xoops_gethandler('member');
$foundusers =& $member_handler->getUsers();
foreach (array_keys($foundusers) as $j) {
echo '<tr><td>'.$foundusers[$j]->getVar("uname").'</td><td>'.$foundusers[$j]->getVar("email").'</td></tr>';
}
echo '</table>';
require(XOOPS_ROOT_PATH.'/footer.php');
?>
Ahhh. Much better. Same end result but now the code is more legible. Let's bring some more xoops standards into it. First thing to do is replace the text "name" and "email" with some language constants. Lets create a folder called language (important: folder name should be all in lower case). Now, inside that folder lets create another folder called english. Inside the folder english create a file called main.php. Now place this code inside main.php:
<?php
define('TT_NAME','Name');
define('TT_EMAIL','Email');
?>
Create another file in this same folder called modinfo.php Inside this file place:
<?php
?>
What we are doing here is creating 2 language constants to replace our current text. Language constants allow users of your module to easily replace module text with their own native language. Now open index.php and change the following:
<?php
// Tutorial
// Created by KaotiK
require('../../mainfile.php');
require(XOOPS_ROOT_PATH.'/header.php');
echo '<table width="100" border="0">
<tr>
<td bgcolor="#99CC99">'.TT_NAME.'</i></td>
<td bgcolor="#66CC99">'.TT_EMAIL.'</td>
</tr>';
$member_handler =& xoops_gethandler('member');
$foundusers =& $member_handler->getUsers();
foreach (array_keys($foundusers) as $j) {
echo '<tr><td>'.$foundusers[$j]->getVar("uname").'</td><td>'.$foundusers[$j]->getVar("email").'</td></tr>';
}
echo '</table>';
require(XOOPS_ROOT_PATH.'/footer.php');
?>
Excellent! We now have language constants in our module.
Building a MySql Table
Almost all modules use forms and a DB in some way, so now I'm going to show how to create a simple form that has it's data inserted into the database (which I will refer to now as DB).
First open xoops_version.php and add the following:
<?php // Tutorial Module // Created by kaotik $modversion['name'] = "Tutorial"; $modversion['version'] = 1.00; $modversion['description'] = "This is a tutorial module to teach how to build a simple module"; $modversion['author'] = "KaotiK"; $modversion['credits'] = "KaotiK"; $modversion['help'] = ""; $modversion['license'] = "GPL see LICENSE"; $modversion['official'] = 0; $modversion['image'] = "images/tutorial.png"; $modversion['dirname'] = "tutorial"; // Admin $modversion['hasAdmin'] = 0; // Menu $modversion['hasMain'] = 1; $modversion['sqlfile']['mysql'] = "sql/mysql.sql"; $modversion['tables'][0] = "tutorial_myform"; ?>
The first line of the new code tells xoops where the sql file is located. The second tells it the table name.
It's good practice to start table count with 0. You should also preappend your module name to the tables, so that latter on, when using phpmyadmin you can easily locate and identify witch tables belong to witch module. This line tells xoops that this module willl create 1 table. This is however only part of the process, we still need to tell xoops what's inside the table, namely what fields and their properties. To do this lets create another folder called sql. Inside folder sql create a file called mysql.sql Open this file and place this code:
CREATE TABLE tutorial_myform ( tt_id int(5) unsigned NOT NULL auto_increment, name varchar(30) NOT NULL default , address varchar(30) NOT NULL default , telephone varchar(30) NOT NULL default , email varchar(30) NOT NULL default , PRIMARY KEY (tt_id), KEY name (name) ) TYPE=MyISAM;
The first line tells xoops to create a table called tutorial_myform. The first field called tt_id is a number field that allows a maximum of 5 digits ( int(5) ), unsigned means it doesn't acept negative values, NOT NULL means it can't be empty and auto_increment will add a number to each row, meaning if the previous row had tt_id=5 then the new row will have tt_id=6. Notice: This field is called tt_id and not id because id is a protected name of mysql, meaning you can't use it for your own purposes. The following 4 fields are similar. They define a field name (name, address, telephone and email), data type ( varchar(30) ) which in this case is a 30 character variable. To read more about this type and more check mysql.com . The next line defines a PRIMARY KEY. All tables should have a primary key defined. Normally I always set my primary keys to each tables id, in this case tt_id. When you have a lot of rows in a table, to increase speed you should index additional fields. Normally I index the ones which are used more often as reference, in this case "name" that's why I have: "KEY name (name)". Notice: the line before )TYPE=MyISAM; should NOT have a comma (,) . You should be carefull not to index too many fields as each new index increases the table size. Finally we define what type of table it is, I personally always use MyISAM but you can experiment with others. You can read more about this here and here.
Ok. We are ready for the next stage. In order for Xoops to create this table we need to do a full uninstall of the module. Then reinstall it. So let's do it.
1- Go into module administration and remove the check from active on the tutorial module. Click Submit. Confirm by clicking submit again.
2- Click back to module administration
3- Click on module uninstall icon which now shows in front of the tutorial module. Confirm by clicking yes. You will now notice a red error message saying that it was unable to drop table xxx_tutorial_myform. This is correct since we told xoops there was a table in xoops_version.
4- Click back to module administration.
5- Now install the module Tutorial.
We now have a xoops module with a table at our disposal! Let's continue.
Using Forms and a Database
Lets build a simple form in index.php
<?php
// Tutorial
// Created by KaotiK
require('../../mainfile.php');
require(XOOPS_ROOT_PATH.'/header.php');
?>
<form name="tutorial_form" method="post" action="index.php">
<table width="400" border="0">
<tr>
<td align="right">Name</td>
<td><input type="text" name="name"></td>
</tr><tr>
<td align="right">Address</td>
<td><input type="text" name="address"></td>
</tr><tr>
<td align="right">Telephone</td>
<td><input type="text" name="tel"></td>
</tr><tr>
<td align="right">Email</td>
<td><input type="text" name="email"></td>
</tr><tr>
<td> </td>
<td><input type="submit" name="submit" value="submit"></td>
</tr>
</table>
</form>
<?php
require(XOOPS_ROOT_PATH.'/footer.php');
?>
Now if you click on tutorial on main menu you will see a form with name, address, telephone and email and a submit button. Clicking on the submit button brings you back to index.php but doesn't do anything.
Insert the following code:
<?php
// Tutorial
// Created by KaotiK
require('../../mainfile.php');
require(XOOPS_ROOT_PATH.'/header.php');
if (isset($_POST['submit'])){
echo 'my name is: '. $_POST['name'];
}
?>
I've only placed the top part of the code to keep this page smaller. Your index.php file should have the entire code.
Now when you click on submit you get a line of text saying "my name is: " and your name. Let me explain what is happening. The php command if is a conditional control. IF something is TRUE (for ex.) then DO something. In this case IF the form button was pressed then print the statment. The submit button is $_POST['submit'] the name 'submit' comes from the name of our button and to check if it exists I used isset which returns TRUE if it does exist and FALSE if it does not.
Now try pressing submit without filling anything. You will notice that it still prints "my name is: " but without a name. Let's create an error message if no name is filled in.
<?php
// Tutorial
// Created by KaotiK
require('../../mainfile.php');
require(XOOPS_ROOT_PATH.'/header.php');
if (isset($_POST['submit'])){
if (empty($_POST['name'])){
echo 'please fill in a name';
} else {
echo 'my name is: '. $_POST['name'];
}
}
?>
Pressing submit with an empty name now prints an error message. You will notice that I'm using an IF condition inside another IF. It's saying: if the form field named "name" is empty then print 'please fill in a name' if not (else) 'my name is: '. $_POST['name']
Putting Data into the DB
Let's take this a step further. We will now insert the form data into our DB table.
<?php
// Tutorial
// Created by KaotiK
require('../../mainfile.php');
require(XOOPS_ROOT_PATH.'/header.php');
if (isset($_POST['submit'])){
if (empty($_POST['name'])){
echo 'please fill in a name';
} else {
$name=$_POST['name'];
$address=$_POST['address'];
$tel=$_POST['tel'];
$email=$_POST['email'];
$query = "Insert into ".$xoopsDB->prefix("tutorial_myform")." (name, address, telephone, email) values ('$name', '$address', '$tel', '$email' )";
$res=$xoopsDB->query($query);
if(!$res) {
echo "error: $query";
} else {
echo "Data was correctly inserted into DB!";
}
}
}
?>
The first 4 lines of new code create variables set to form values. I've done it this way for a better understanding of what's happening. The next line $query builds the line that will be used by $xoopsDB in
$res=$xoopsDB->query($query);
The next line:
if(!$res)
checks if any error ocurred when accessing the DB. If all went fine print "Data was correctly inserted into DB!". In later tutorials I will teach you about text sanitation and it's importance.
Listing Database Contents
Now we are going to create a button to list all the content in our table.
<?php
// Tutorial
// Created by KaotiK
require('../../mainfile.php');
require(XOOPS_ROOT_PATH.'/header.php');
if (isset($_POST['listall'])){
echo '<table width="100" border="0">
<tr>
<td bgcolor="#99cc99">Name</td>
<td bgcolor="#66cc99">Address</td>
<td bgcolor="#99cc99">Telephone</td>
<td bgcolor="#66cc99">Email</td>
</tr>';
$query = $xoopsDB->query(' SELECT * FROM ' . $xoopsDB->prefix('tutorial_myform'));
while($myrow = $xoopsDB->fetchArray($query) )
{
$name = $myrow['name'];
$address = $myrow['address'];
$telephone = $myrow['telephone'];
$email = $myrow['email'];
echo '<tr><td bgcolor="#99cc99">'.$name.'</td><td bgcolor="#66cc99">'.$address.'</td><td bgcolor="#99cc99">'.$telephone.'</td><td bgcolor="#66cc99">'.$email.'</td></tr>';
}
echo '</table>';
}
if (isset($_POST['submit'])){
if (empty($_POST['name'])){
echo 'please fill in a name';
} else {
$name=$_POST['name'];
$address=$_POST['address'];
$tel=$_POST['tel'];
$email=$_POST['email'];
$query = "Insert into ".$xoopsDB->prefix("tutorial_myform")." (name, address, telephone, email) values ('$name', '$address', '$tel', '$email' )";
$res=$xoopsDB->query($query);
if(!$res) {
echo "error: $query";
} else {
echo "Data was correctly inserted into DB!";
}
}
}
?>
<form name="tutorial_form" method="post" action="index.php">
<table width="400" border="0">
<tr>
<td align="right">Name</td>
<td><input type="text" name="name"></td>
</tr><tr>
<td align="right">Address</td>
<td><input type="text" name="address"></td>
</tr><tr>
<td align="right">Telephone</td>
<td><input type="text" name="tel"></td>
</tr><tr>
<td align="right">Email</td>
<td><input type="text" name="email"></td>
</tr><tr>
<td><input type="submit" name="listall" value="List All"></td>
<td><input type="submit" name="submit" value="submit"></td>
</tr>
</table>
</form>
<?php
require(XOOPS_ROOT_PATH.'/footer.php');
?>
There are 2 changes here. One is a new button named listall that, when pressed will list all rows in our table. The other is an IF condition to check if the listall button was pressed.
There is one more thing to do, that is replace the text with language constants so let's take care of that. Open file main.php found in folder /language/english and add this code:
<?php
define('TT_NAME','Name');
define('TT_EMAIL','Email');
define('TT_ADDRESS','Address');
define('TT_TELEPHONE','Telephone');
?>
Here is the final code for index.php:
<?php
// Tutorial
// Created by KaotiK
require('../../mainfile.php');
require(XOOPS_ROOT_PATH.'/header.php');
if (isset($_POST['listall'])){
echo '<table width="100" border="0">
<tr>
<td bgcolor="#99cc99">'.TT_NAME.'</td>
<td bgcolor="#66cc99">'.TT_ADDRESS.'</td>
<td bgcolor="#99cc99">'.TT_TELEPHONE.'</td>
<td bgcolor="#66cc99">'.TT_EMAIL.'</td>
</tr>';
$query = $xoopsDB->query(' SELECT * FROM ' . $xoopsDB->prefix('tutorial_myform'));
while($myrow = $xoopsDB->fetchArray($query) )
{
$name = $myrow['name'];
$address = $myrow['address'];
$telephone = $myrow['telephone'];
$email = $myrow['email'];
echo '<tr><td bgcolor="#99cc99">'.$name.'</td><td bgcolor="#66cc99">'.$address.'</td><td bgcolor="#99cc99">'.$telephone.'</td><td bgcolor="#66cc99">'.$email.'</td></tr>';
}
echo '</table>';
}
if (isset($_POST['submit'])){
if (empty($_POST['name'])){
echo 'please fill in a name';
} else {
$name=$_POST['name'];
$address=$_POST['address'];
$tel=$_POST['tel'];
$email=$_POST['email'];
$query = "Insert into ".$xoopsDB->prefix("tutorial_myform")." (name, address, telephone, email) values ('$name', '$address', '$tel', '$email' )";
$res=$xoopsDB->query($query);
if(!$res) {
echo "error: $query";
} else {
echo "Data was correctly inserted into DB!";
}
}
}
?>
<form name="tutorial_form" method="post" action="index.php">
<table width="400" border="0">
<tr>
<td align="right"><?php echo TT_NAME; ?></td>
<td><input type="text" name="name"></td>
</tr><tr>
<td align="right"><?php echo TT_ADDRESS; ?></td>
<td><input type="text" name="address"></td>
</tr><tr>
<td align="right"><?php echo TT_TELEPHONE; ?></td>
<td><input type="text" name="tel"></td>
</tr><tr>
<td align="right"><?php echo TT_EMAIL; ?></td>
<td><input type="text" name="email"></td>
</tr><tr>
<td><input type="submit" name="listall" value="List All"></td>
<td><input type="submit" name="submit" value="submit"></td>
</tr>
</table>
</form>
<?php
require(XOOPS_ROOT_PATH.'/footer.php');
?>
That completes this tutorial. I hope you found it usefull.
| Here is the completed module. Check this with your own code to see if they match. |
Tutorial module Completed Tutorial |

![[Main Page]](/modules/mediawiki/images/mediawiki.png)






