LOGIC Library

This site is the Logic involvement in sharing expertise and skills acquired in daily work. The goal is to create a solid knowledge base and share best practices in software development and systems management.

More info about us can be found on logicsistemi.it.

Developing MVC components for Joomla! 2.5 - part 5

It 's time to put all the code at the right place and create the final missing piece of our component: the model. Starting from scratch the code to write would be a lot, but Joomla! helps us with the classes that already implement most of what we need.

To complete the example we abandon the words Hello, World!, in favor of data coming from a database table.

Creating the model

On the basis of what has been explained the structure MVC we expect that in the model is present all the necessary code to retrieve data from a given source (in our case the same database of Joomla!), so that such data could be available for the view.

This is exactly what happens, but if we talk about the MySQL database already used by Joomla! for its standard operativity, all the code has already been implemented in a class that derives from JModel. This class is JModelList and, as its name implies, contains the code necessary to display a list of items read from a MySQL database table.

Under our admin folder let's create the models directory and, inside it, the file persons.php with the following contents:

<?php
defined('_JEXEC') or die();
jimport( 'joomla.application.component.modellist' );
class RegistryModelPersons extends JModelList
{
    function getListQuery()
    {
        $db = JFactory::getDBO();
        $query = $db->getQuery(true);
        $query->select('id, name, surname');
        $query->from('#__registry_persons');
        return $query;
    }
}

We note first that the class name follows the usual logic, starting with the prefix that comes from the name of our component, up to the suffix that represents the name of our specific model and must match with the view, so that it will be able to find it.

Then we define a function that returns an object of type JDatabaseQuery. For this object we set up basic information for building our query: the list of select fields and the name of the table where we get them.

For sure you have notice that the name of the table starts with # __. This notation is necessary because the prefixes of the tables may be set differently for every installation of Joomla!. The #__ string will be automatically replaced with the correct prefix, and therefore the class will be accessing the correct database table (whose name we will never have to worry about during development).

Database query

To make everything work the database table must be created. This operation can be made, in development, manually, however the packages of Joomla! are also able to take care of these operation.

We create the sql forlder inside the admin folder and, insite it, the file install.sql with the following contents:

CREATE TABLE #__registry_persons (
   id   INTEGER AUTO_INCREMENT not null,
   name VARCHAR(255)                   ,
   surname VARCHAR(255)                ,
   CONSTRAINT pk_#__registry_persons PRIMARY KEY (id)
)   ENGINE=MyISAM DEFAULT CHARSET=utf8;
INSERT INTO #__registry_persons (name, surname)
VALUES ('John', 'Smith'), ('Mariah', 'White'), ('Frank', 'Black');

As you can see it is a simple query that creates the database table. We always substitute Joomla! database tables prefix with the string # __. At the end are inserted some sample records to give something to display to our example.

This query will be launched in a transaction during installation (we will see later how to specify it).

The name given to the table was made using the name of the component to be sure it will not conflicts with other components, but you are free to assign the name you prefer.

The id field used as the primary key reflects the Joomla! standards, but for it you can use whichever method you prefer, even if this change could reduce some automatisms that will be useful later.

In addition to the installation files we need to create the uninstall file. It must restore the original situation of the database in the case the component is removed. In our case we will drop the newly created table.

Create, in the same folder, the file uninstall.sql sql with the following contents:

DROP TABLE IF EXISTS #__registry_persons;

Files created are executed as indicated during installation and removal of the package. If we install the package as in the previous posts these files are not executed, because is occuring an upgrade and not an install.

Since version 1.6 Joomla! introduced a mechanism that allows to execute queries to update our database. To enable it, create, for each version, an upgrade file that lets you perform the necessary operations.

Create, inside the sql folder, another folder called updates. Copy the file install.sql in it and rename it 1.0.3.sql.

Since this is the first time we set up this mechanism in our examples, it will not work, because Joomla! has not stored some required informations about the versione for the database. The presence of the file, however, will enable everithing for subsequent updates.

It 's important to remember to create the update file for each version that we made, possibly leaving it empty. Its presence is necessary for Joomla! to  properly update the information on the latest changes made to the database.

Arrangement of view and templates

As a final step we modify the view and the template previously created so that they use the model to retrieve data and will dispay them in the standard Joomla! format.

Let's start changing view code as follows:

<?php
// No direct access to this file
defined('_JEXEC') or die('Restricted access');
jimport( 'joomla.application.component.view' );
class RegistryViewPersons extends JView
{
    function display($tpl = null)
    {
        $this->items = $this->get('Items');
        parent::display($tpl);
    }
}

The get function of JView only calls the function specified as a parameter of the model, always with the prefix get. In this case the function getItems of the model is called.

As you can see we haven't told to instantiate a model. This is automatically done by JView.

In the model, in addition, the function getItems has not been defined. It is already present in JModelList and returns an array with all records collected through the query that we have defined (in our case, all records in the table # __registry_persons).

I recommend you to take a loog att JModelList and JView source code. There will be pieces that can be cumbersome, but will give you an idea of how these classes and the functions that we will use in the tutorial work. You can find definitions of classes iin the Joomla documentation or in the Joomla! installation on your site in the /libraries/joomla/application/component folder.

The template editing is a bit more complex, because we are not going to list only the data from the table, but we will create an HTML page for display data that will get a look very similar to other management pages in Joomla!.

<?php
// no direct access
defined( '_JEXEC' ) or die( 'Restricted access' );
?>
<form action="index.php" method="post" name="adminForm" id="adminForm">
	<div id="editcell">
		<table class="adminlist">
			<thead>
				<tr>
					<th>NAME</th>
					<th>SURNAME</th>
					<th>ID</th>
				</tr>
			</thead>
			<tbody>
<?
		$k = 0;
		foreach ($this->items as &$row)
		{
?>
				<tr class="row">
					<td><?=$row->name?></td>
					<td><?=$row->surname?></td>
					<td><?=$row->id?></td>
				</tr>
<?
			$k = 1 - $k;
		}
?>
			</tbody>
		</table>
	</div>
</form>

As you can see is a simple HTML table for which were set the appropriate id and classes that will be used by CSS to create the correct format.

The table is included in a form that, at this stage may seem unnecessary, but it will heavily used in next post.

The rest of the code iterate the array returned by getItems and prints the different values. One caveat about the class set on tr: it allows to toggle the color of the lines.

Creating the package

The structure on our PC will now be the following:

com_registry
  admin
    controller.php
    index.html
    registry.php
    models
      persons.php
    sql
       install.sql 
       uninstall.sql 
       updates
         0.0.4.sql 
    views
      index.html
      persons
        index.html 
        view.html.php
        tmpl
          default.php
          index.html
  site
    registry.php
    index.html
  registry.xml

While the file anagrafiche.xml must be modified in the following way:

<?xml version="1.0" encoding="UTF-8"?>
<install type="component" version="2.5.0" method="upgrade">
    <name>Registry</name>
    <author>Edy Incoletti</author>
    <authorEmail>edy.incoletti@logicsistemi.it</authorEmail>
    <authorUrl>http://library.logicsistemi.it</authorUrl>
    <creationDate>March 2012</creationDate>
    <version>0.0.4</version>
    <description>Registry management for the tutorial.</description>     <files folder="site">         <filename>index.html</filename>         <filename>registry.php</filename>     </files> <install folder="admin">         <sql>             <file charset="utf8" driver="mysql">sql/install.sql</file>         </sql>     </install>     <uninstall folder="admin">         <sql>             <file charset="utf8" driver="mysql">sql/uninstall.sql</file>         </sql>     </uninstall> <update> <schemas> <schemapath type="mysql">sql/updates</schemapath> </schemas> </update>     <administration>         <files folder="admin">             <filename>index.html</filename>             <filename>registry.php</filename>             <filename>controller.php</filename> <folder>models</folder> <folder>sql</folder>   <folder>views</folder>         </files>     </administration> </install>

Compared to previous version has been updated the version number and introduced a tag to copy the whole model folder from the admin part and the sql folder that contains the queries to run during install, uninstal or upgrade.

We have also added install and uninstall sections with the path of sql files to launch during installation and removal of the component. The update section will occur during upgrades.

Remove the existing component and install the new one with your package or with that you find here and this time our page we will give  some satisfaction by showing data coming from the database.

Comments   

 
#1 kamal 2013-04-18 11:49
in part5 model and db acces i ahve this error

Warning: mysql_num_rows( ) expects parameter 1 to be resource, boolean given in C:\wamp\www\Joo mla3\libraries\ joomla\database \database\mysql .php on line 293
Quote
 
 
#2 Edy Incoletti 2013-04-18 14:25
This warning indicates that the query has failed.
Check your code and the presence of the required tables (are created during the installation).
Quote
 
 
#3 kamaljit laishram 2013-07-19 14:01
very nice tutorial with clear explanation
i hv this problem
database table not created automatically from sql file
Quote
 
 
#4 Eric Vaillancourt 2013-07-30 18:38
Very nice tuto...

When I run it on my server, the variables are not displayed:
name?> surname?> id?>

are displayed instead...any idea??
Quote
 
 
#5 Edy Incoletti 2013-08-12 08:30
Quoting kamaljit laishram:
very nice tutorial with clear explanation
i hv this problem
database table not created automatically from sql file

Hi kamaljit,
Check the manifest file and folder names.
Quote
 
 
#6 Edy Incoletti 2013-08-12 08:31
Quoting Eric Vaillancourt:
Very nice tuto...

When I run it on my server, the variables are not displayed:
name?> surname?> id?>

are displayed instead...any idea??

My code required the support for short php opening tags that, in Windows, is by default disabled.
Turn it on or replace the php opening tag by using the long syntax with php.
Quote
 
 
#7 Tran Dinh Trong 2013-10-11 12:36
Thanks Edy Incoletti very much. I am finding how to write joomla components, and I saw your blog.

Quoting kamaljit laishram:
very nice tutorial with clear explanation
i hv this problem
database table not created automatically from sql file

"Create, inside the sql folder, another folder called updates. Copy the file install.sql in it and rename it 1.0.3.sql." --> change to 0.0.4.sql
Quote
 
 
#8 Tayo 2014-02-23 08:45
Thanks for this lovely tutorial... I was i tried installing the component at this stage but i got the following error "Another menu item with the same parent has this alias
Error building Admin Menus".. Any help about this error?
Quote
 
 
#9 Edy Incoletti 2014-02-24 11:14
Quoting Tayo:
Thanks for this lovely tutorial... I was i tried installing the component at this stage but i got the following error "Another menu item with the same parent has this alias
Error building Admin Menus".. Any help about this error?

Sometimes appens when an installation fails.
The only solution I've found is to delete the voice from the #__menu table.
Quote
 
 
#10 Haidar 2014-08-15 10:04
wow! this is what i was looking for.
And the best part, you've better explained many things than official documentaion
thanx a lot
Quote
 
 
#11 Martin 2014-09-04 17:36
Thank you for the great tutorial! We need more tutorials like this.
Quote