You are on page 1of 58

Joomla Component Development .

Joomla
Component Development

Author Prepared On Revision Approved By


th
Prabhu Patil 18 January, 2009

This document is solely meant for internal use of the designated programmers at “Carmel”
development center and is classified as highly confidential. Please ensure that you don’t
leave copies of this document on your local disk drives or circulate in any form without
explicit permission.

The only controlled copy of this document is the on-line version maintained on VSS server. It is
the user's responsibility to ensure that any copy of the controlled version is current and complete,
and that the obsolete copies are discarded.

Confidential – All rights reserved. 1


Joomla Component Development .

Table of Content

Introduction:.........................................................................................................................3
Section 1: The components' table in joomla's database.......................................................4
Section 2: The entry point....................................................................................................5
Section 3 – The backend tasks –The default task................................................................8
Section 3.1 the default controller task (display)..............................................................8
Section 3.2 The model - Getting the students from the DB ..........................................12
The code here it is (Model):.......................................................................................13
Section 3.3 - The view - Listing the students.................................................................24
Here’s the view code (list):........................................................................................24
Section 4 – The backend tasks – The edit task..................................................................37
Section 4.1 – The controller task: edit...........................................................................37
Code for edit method:................................................................................................37
Section 4.2 The model – Getting a student through its id..............................................38
Section 4.3 The view – form to edit the student............................................................38
Section 5: The backend tasks - Save..................................................................................46
Section 5.1 – The controller task: save..........................................................................46
Here’s the code (save() method in studentsController.php): .....................................46
Here is the Code (saveStudent($student) method in …/models/students.php)..........46
Section 5.2 JTABLE......................................................................................................48
Section 5.3 The Model – Adding the save functionality................................................50
Here is the Code (saveStudent($student) method in …/models/students.php)..........50
Section 6: The backend tasks – The add task.....................................................................52
Section 6.1: The controller task: add ............................................................................52
Here’s the add() function in controller code: ............................................................52
Section 6.2: The view - Form to edit the student (revisited).........................................52
Here’s the displayAdd() method in view.php code:...................................................53
Section 6.3: The model – New students.........................................................................53
Here’s the getNewStudent() ..//models/students.php code: ......................................53
Section 7: The backend tasks: The remove task ...............................................................55
Section 7.1: The controller task: remove ......................................................................55
Here is remove() method code in studentsController.php ........................................55
Section 7.2: The model – Deleting students..................................................................55
Here is the deleteStudents() in ..//models/students.php.............................................55
Section 8: Download & Installation...................................................................................58
Unzip Student_Component............................................................................................58
You will find:.................................................................................................................58
Com_students (component)...........................................................................................58
Joomla_Component_Development .doc (Document)....................................................58
jos_components.sql (sql query).....................................................................................58
jos_Students.sql (sql query)...........................................................................................58
Place com_students folder in joomla path ..\\administrator\components\.....................58
Execute jos_components.sql and jos_Students.sql on mysql joomla database............58
That’s it..........................................................................................................................58

Confidential – All rights reserved. 2


Joomla Component Development .

TEST:.............................................................................................................................58
Login to Joomla. Click on component. Find ‘Manage Student’ link. Click on this &
Explore...........................................................................................................................58
If you have any queries, please free to mail me.
(mailto:prabhu.patil@reachwell.net?subject=Joomla Queries).....................................58
Thank you,.....................................................................................................................58
Prabhu Patil....................................................................................................................58

Component Development with Example: The


Backend
Introduction:
This document is about a Joomla component named "Students" that manage our Students
List, Add, Edit and Remove feature. This new version of Joomla (1.5) uses an approach
to component development based on the Model-View-Component design pattern.

So what is this of the Model View Controller pattern? Well, if you look for it in this book
“Design patterns – Elements of Reusable Object Oriented Software” (Erich Gamma, et
all), which is probably the most popular book about design patterns, you’ll find this:

“MVC consists of three kinds of objects. The Model is the application object, the View is
its screen presentation, and the Controller defines the way that the user interface reacts to
the user input. Before MVC user interface designs tended to lump these objects
together…”

So the basic idea is that you have a Model of your data, that is unaware of the views that
might exists to represent it, you have one or more views of that model that represent it,
and you have a controller, which is responsible for receiving input from the views and
updating the model. For creating our Joomla component we’ll have to write a model, a
view and a controller for it

We have to do the backend, which will allow us to manage our Students: List, Add, Edit
and Remove them.

Confidential – All rights reserved. 3


Joomla Component Development .

Section 1: The components' table in joomla's database


The first thing we’ll do is to insert a new record in the Joomla’s table that stores the
installed components. By doing this you can test your component while you’re
developing it, instead of coding it all.

To do this you’ll have to have phpmyadmin or you can use the MySQL command line
client. In phpmyadmin this is what you have to do:

(I’m using version: 5.2.6 of phpmyadmin)

1. Open phpmyadmin and select the database that you’re using for your joomla
installation;
2. Select the table jos_components (it might have a different prefix (jos_), you
choose the prefix when you install joomla (jos is the default prefix);
3. Click on the insert tab;
4. Fill the Value column with the values:
1. name: Students
2. link: option=com_students
3. admin_menu_link: option= com_students
4. option: com_students

And that’s it, the rest of the fields leave them with the default values.

Note: If you want to use the MySQL command line client to do this, remember that
option is a reserved keyword, so you have to write it like this `option` when you’re
writing your SQL insert statement. Here’s what it should look like:

INSERT INTO jos_components (name, link, admin_menu_link, `option`)


VALUES (‘Students’, ‘option= com_students’, ‘option= com_students’, ‘com_students’)

To use this SQL insert statement in the MySQL command line client you have to login,
choose the right database (syntax: use DATABASE_NAME; to view the available
databases write: show databases; ) and only then you can use it.

So now, if you log in to your joomla site back end you should see, under the components
tab, the “Students” component. If you click on it, you get an error (404 – Component not

Confidential – All rights reserved. 4


Joomla Component Development .

found). If this is what you got, everything is going well, and we can now start to build our
component.

Section 2: The entry point


The first thing we have to do is the entry point. But for the backend the naming
convention for the file that will contain the code of the entry point is different. Instead of
being just the component name followed by “.php”, in the backend it’s:
admin.[ComponentName].php. So in our case that will be: admin.students.php and it
should be located in:

Place where you’ve installed


joomla/administrator/components/com_students/admin.students.php
the entry’s point code in the backend is exactly the same as the frontend’s, here it is:

<?php

// no direct access
defined( '_JEXEC' ) or die( 'Restricted access' );

// Require the controller


require_once( JPATH_COMPONENT.DS.'studentsController.php' );

// Create the controller


$controller = new StudentsController();

// Perform the Request task


$controller->execute( JRequest::getVar( 'task' ) );

// Redirect if set by the controller


$controller->redirect();

?>

Please note that JPATH_COMPONENT now gives you the path to the backend of our
component, in this case: place where you’ve installed
joomla/administrator/components/com_students

Important this about this piece of code:

Confidential – All rights reserved. 5


Joomla Component Development .

The first line: defined(‘_JEXEC’) or die…: What this means is that if the constant
‘_JEXEC’ is not defined the application exits and the only thing you’ll see is the
“Restricted Access” message.

DETAIL 2.1.1: The constant _JEXEC is defined in the index.php file, so if you try to
access the students.php file directly, by typing the URL: http://folder where you’ve
installed joomla under apache’s htdocs folder/components/com_students/students.php,
you’ll get that “Restricted Access” message because _JEXEC won’t be defined.

Second line of code, the


“require_once(JPATH_COMPONENT.DS.'studentsController.php' );” will load the
controller we’ll do next. What you need to know about this is that JPATH_COMPONENT
is a joomla constant that contains the path to where your component is, and DS is also a
joomla constant that means “Directory Separator” (it’s defined this way to work both in
windows and unix environments).

DETAIL 2.1.2: The JPATH_COMPONENT constant contains the frontend’s path to the
component if your code is running in the frontend or it has the backend’s path to the
component if your code is running in the back end. This is because the
JPATH_COMPONENT constant is defined using another constant, the JBASE_PATH
constant that contains the path to the frontend if you’re in the frontend or the backend if
you’re in the backend. The actual files where theses constants are defined are:

JBASE_PATH: index.php (frontend) and administrator/index.php(backend)


JPATH_COMPONENT: libraries/joomla/application/component/helper.php (the method
you should look for is render Component).
JPATH_COMPONENT_SITE: same as above
JPATH_COMPONENT_ADMINISTRATOR: same as above

These last two constants contain the path to the frontend part of the component and the
backend part of the component and are independent of JBASE_PATH.

Forth line: “$controller->execute( JRequest::getVar( 'task' ) );” this tells our soon to be
created controller which task it should perform. What is important for you to know here
is that if task is not defined in the URL the JRequest::getVar(‘task’) returns null, and the
execute method from the controller will execute the controller’s default task (the default
task is display, I’ll explain this better when we do the controller).

Confidential – All rights reserved. 6


Joomla Component Development .

Last line: “$controller->redirect();” .What you need to know about this is that you can
setRedirect in the controller to the URL where the browser should redirect when this
method is called. If you don’t use the setRedirect method in the controller, the redirect
method just returns false.

And that’s the entry point. Don’t try this just yet; it won’t work because we still have to
define the controller, the view and the model, which we will do next.

Confidential – All rights reserved. 7


Joomla Component Development .

Section 3 – The backend tasks –The default task


Section 3.1 the default controller task (display)

Our backend controller will be more complex than our frontend’s. It will have to deal
with more tasks: add, edit, remove and display the list of students. I think the easiest way
to do this is iteratively. What I mean is that it is easier if we handle each task at a time.
For example, if we want to start with the display task, that will list the students, we do the
code for the controller, then do the model, do the view and test, and then do the other
tasks (this way it is easier to test if everything is going well). It is easier to explain it this
way than post all the code from the controller here, describe it, and then do the same for
the models and views.

So, let’s start with the controller. We’ve called the file studentsController.php we have to
put it in the backend folder, so put the file here:

Folder where you’ve installed


joomla/administrator/components/com_students/studentsController.php

Here’s the code that handles the default task (display):

<?php

// no direct access
defined( '_JEXEC' ) or die( 'Restricted access' );

jimport('joomla.application.component.controller');

/**
* Students Component Administrator Controller
*/
class StudentsController extends JController
{

/**
* Method to display the view
*
* @access public
*/
function display()
{

Confidential – All rights reserved. 8


Joomla Component Development .

//This sets the default view (second argument)


$viewName = JRequest::getVar( 'view', 'list' );
//This sets the default layout/template for the view
$viewLayout = JRequest::getVar( 'layout', 'listlayout' );

$view = & $this->getView($viewName);

// Get/Create the model


if ($model = & $this->getModel('students')) {
//Push the model into the view (as default)
//Second parameter indicates that it is the default model for the view
$view->setModel($model, true);
}

$view->setLayout($viewLayout);
$view->display();

}
}

The default task for the controller is display, so we redefine the display method. This time
we want to load a view named list and a model called students. To know how the classes
and files for the model and view should be named (see below). The file and class names:

• view file: folder where you’ve installed


joomla/administrator/com_students/views/list/view.php
• view class name: StudentsViewList
• view layout/template file: folder where you’ve installed
joomla/administrator/com_students/views/list/tmpl/listlayout.php (Remember that
the file name is lowercase)
• model file: folder where you’ve installed
joomla/administrator/com_students/models/students.php (Remember, that even if
you name your model with uppercase character, the file name has to be all
lowercase)
• model class name: StudentsModelStudents

2nd line of code: “jimport('joomla.application.component.controller'); “. What you need


to know about this is that it will require_once the file named controller.php located in
libraries/joomla/application/component. This file contains the definition of the class
JController that we are extending here.

The rest is just creating the StudentsController class, that extends JController and
redefining the JController’s display method to do exactly what JController’s display

Confidential – All rights reserved. 9


Joomla Component Development .

method does. Why did I do this? Just to tell you about the JController’s display method.
This default JController’s display method does this:

• Gets the name of the view:


o If the parameter view is in the request, for example you have an URL like
this: index.php?option=com_students&view=list, the view name will be
‘list’.
o If there’s no view parameter in the request the view name will be the
controller class name but without ‘Controller’. In our Students component,
the controller class name is StudentsController, so the view name is
‘students’.
• Gets the name of the view’s layout from the request
o If the parameter layout is in the request, for example, you have an URL
like this: index.php?option=com_students&view=list&layout=listlayout,
the view’s layout/template will be called listlayout.
o If there is no layout parameter in the request the default layout is called
default.

You might be wondering right now, what is this thing, the view’s layout, I haven’t told
you about it. Well, I guess the people that developed the JView class(the class that we’ll
extend to create our view)decided that it would be nice to have a separate file for the
view class definition and the file that will have HTML that actually displays the view
(with some php mixed in) . This way you have a view class file, without HTML, and all
the HTML mixed with php code in the layout file.

I wouldn’t call it layout or template though, because it suggests that you can have two
layouts for the same view, and in the MVC, shouldn’t that be two different views? That’s
just how I see it anyway… Disagree? Feel free to email
me(mailto:prabhu.patil@reachwell.net?subject=should not be two different views
(MVC), maybe I didn’t get it right!
Now, some other important things that you also need to know about the view’s class
name, the view’s file name and the layout’s file name that I haven’t told you:

• The view’s class name


[ControllerClassNameWithoutController]View[ViewName]
• The view’s file name is views/[ViewNameLowercased]/view.html.php
• Layout file name:
views/[ViewNameLowercased]/tmpl/[LayoutNameLowercased].php

About the [LayoutNameLowercased].php file name, the lowercase part is really


important! Because if you're working in Windows and you decide to name your layout,
listLayout, and you forget that the layout file name has to be lowercase (so you name it
listLayout.php). What will happen is that it will work ok in your local windows machine,
but as soon as you upload the component to your website powered by a Linux server it
will stop working, and you'll get an error saying the layout file is not found. Why does
this happen? Because file names in Windows environments are not case sensitive, but in

Confidential – All rights reserved. 10


Joomla Component Development .

Linux environments they are. So, don't forget this so that you don't end up banging your
head in the wall needlessly.

In our case, if we have an URL like this:


index.php?option=com_students
So, it’s all defaults in this example:

• View Class file: folder where you’ve installed


joomla/components/com_students/views/students/view.html.php (the view file
name is always view.[DocumentType].php) [I don’t really know about
DocumentType]
• View Class Name: StudentsViewStudents
• View Layout file: folder where you’ve installed
joomla/components/com_students/views/students/tmpl/default.php

Another example:
index.php?option=com_students&view=list&layout=listlayout

• View Class file: folder where you’ve installed


joomla/components/com_students/views/list/view.html.php
• View Class Name: StudentsViewList
• View Layout file: folder where you’ve installed
joomla/components/com_students/views/list/tmpl/listlayout.php

And these are the secrets behind the naming conventions in Joomla component
development. Hope I didn’t forget anything, if you think there is something wrong or
unclear feel free to let me know.

DETAIL 3.1.2: Are you wondering why the views’ file and the layout file are under a folder
called views and tmpl, respectively? Well I did too, and the answer to that is: the default
folder where the controller will look for the views is views, and the default folder where the
views will look for layouts is tmpl. Because I’m describing the controller right now, I’ll take
this chance to tell you about the default parameters that you can change, in the JController’s
contructor.

• name: the controllers name, this will change all that I described earlier, instead of
parsing the name of the controller class to take out the “Controller” part, the name
you put here is used instead.
• base_path: usually has the path to the component, can’t really remember any reason
why you want to change its default value…
• default_task: remember I told you that the default task for the controller was display,
you can change that here. Note that this is the method that is called if there is no task
parameter in the URL.
• model_path: default value is base_path/models. This is the folder where the
controller will look for the models.
• view_path:
Confidential default value is base_path/views. Here you have it, that’s why if you11
– All rights reserved. use
the defaults you have to place your view files under this folder
Joomla Component Development .

Did I lose you? Well, I still haven’t finished explaining the JController default display
method that we’re using.
Next, there’s the how the model file is loaded and how the model class should be named.
If you use the default JController’s display method the name of the view and the name of
the model have to be the same. Remember, the default view name is the controller’s name
without “Controller” if the parameter view is not present in the URL, or, if the parameter
view is present in the request URL, then the view name will have the value specified in
the url.

From now on, I’ll refer to the model name, whose default value is the view name or the
view parameter value in the url, as ModelName.
So, the file that contains the definition of the model should be named [ModelName].php
and be located in models/.
The class name should be [ControllerNameWithoutController]Model[ModelName].
The view gets linked to the model, so you can access the model through the view as we’ll
see later.

So, the default display method, loads the view and model (with the rules I described
above), and in the end calls the view’s display method (we’ll look at it when we create
the view).

So a lot goes on in the Controller that at first glance you might not be aware of. As a
curiosity, I’ll show you an alternative to using the JController’s default display method:

Section 3.2 The model - Getting the students from the DB

Let’s create our model with a method to load all the students in the database and return
them in an array, so that we can display them in the view. Remember, the model is named
students.

file name: folder where you’ve installed


joomla/administrator/components/com_students/models/students.php

Confidential – All rights reserved. 12


Joomla Component Development .

class name: StudentsModelStudents

The code here it is (Model):

<?php

//No direct acesss

defined('_JEXEC') or die();

jimport('joomla.application.component.model');

class StudentsModelStudents extends JModel {

/**

* Category ata array

* @var array

*/

var $_data = null;

/**

* Items total

* @var integer

*/

var $_total = null;

/**

* Pagination object

* @var object

*/

var $_pagination = null;

/**

Confidential – All rights reserved. 13


Joomla Component Development .

* Constructor

* @since 1.5

*/

function __construct(){

parent::__construct();

global $mainframe, $option;

// Get pagination request variables

$limit = $mainframe->getUserStateFromRequest('global.list.limit', 'limit',


$mainframe->getCfg('list_limit'), 'int');

$limitstart = $mainframe->getUserStateFromRequest($option.'.limitstart',
'limitstart', 0, 'int');

// In case limit has been changed, adjust it

$limitstart = ($limit != 0 ? (floor($limitstart / $limit) * $limit) : 0);

$this->setState('limit', $limit);

$this->setState('limitstart', $limitstart);

/**

* Method to get Students item data

* @access public

* @return array

Confidential – All rights reserved. 14


Joomla Component Development .

*/

function getData(){

// if data hasn't already been obtained, load it

if (empty($this->_data)) {

$query = $this->_buildQuery();

$this->_data = $this->_getList($query, $this->getState('limitstart'), $this-


>getState('limit'));

return $this->_data;

/**

* Method to get the total number of student items

* @access public

* @return integer

*/

function getTotal()

// Lets load the content if it doesn't already exist

if (empty($this->_total))

$query = $this->_buildQuery();

$this->_total = $this->_getListCount($query);

Confidential – All rights reserved. 15


Joomla Component Development .

return $this->_total;

/**

* Method to get a pagination object for the Students

* @access public

* @return integer

*/

function getPagination()

// Lets load the content if it doesn't already exist

if (empty($this->_pagination))

jimport('joomla.html.pagination');

$this->_pagination = new JPagination( $this->getTotal(), $this-


>getState('limitstart'), $this->getState('limit') );

return $this->_pagination;

function _buildQuery()

// Get the WHERE and ORDER BY clauses for the query

$where = $this->_buildContentWhere();

Confidential – All rights reserved. 16


Joomla Component Development .

$orderby = $this->_buildContentOrderBy();

$query = ' SELECT * from #__student AS a '

.$where

.$orderby

return $query;

function _buildContentOrderBy()

global $mainframe, $option;

$filter_order = $mainframe->getUserStateFromRequest(
$option.'filter_order','filter_order','a.students_firstname', 'cmd' );

$filter_order_Dir = $mainframe->getUserStateFromRequest(
$option.'filter_order_Dir','filter_order_Dir', '', 'word' );

if ($filter_order == 'a.students_firstname'){

$orderby = ' ORDER BY a.students_firstname'.'


'.$filter_order_Dir;

} else {

$orderby = ' ORDER BY '.$filter_order.' '.$filter_order_Dir.',


a.students_firstname , a.ordering ';

return $orderby;

Confidential – All rights reserved. 17


Joomla Component Development .

function _buildContentWhere()

global $mainframe, $option;

$db =& JFactory::getDBO();

$filter_state = $mainframe->getUserStateFromRequest(
$option.'filter_state', 'filter_state', '', 'word'
);

$filter_active = $mainframe->getUserStateFromRequest(
$option.'filter_active', 'filter_active', 0, 'int' );

$filter_order = $mainframe->getUserStateFromRequest(
$option.'filter_order', 'filter_order', 'a.students_firstname', 'cmd' );

$filter_order_Dir = $mainframe->getUserStateFromRequest(
$option.'filter_order_Dir', 'filter_order_Dir', '', 'word'
);

$search = $mainframe-
>getUserStateFromRequest( $option.'search', 'search',
'', 'string' );

$search = JString::strtolower( $search );

$where = array();

if ($search) {

$where[] = 'LOWER(a.students_firstname) LIKE '.$db->Quote(


'%'.$db->getEscaped( $search, true ).'%', false );

if ( $filter_state ) {

if ( $filter_state == 'P' ) {

$where[] = 'a.published = 1';

Confidential – All rights reserved. 18


Joomla Component Development .

} else if ($filter_state == 'U' ) {

$where[] = 'a.published = 0';

if ($filter_active > 0) {

$where[] = 'a.students_active = '.(int) $filter_active;

$where = ( count( $where ) ? ' WHERE '. implode( ' AND ',
$where ) : '' );

return $where;

function getStudent($id){

$query = 'SELECT * FROM #__student'.

' WHERE id = '.$id;

$db = $this->getDBO();

$db->setQuery($query);

$student = $db->loadObject();

if ($student === null)

JError::raiseError(500, 'Student with ID: '.$id.' not found.');

else

return $student;

Confidential – All rights reserved. 19


Joomla Component Development .

/**

* Method to store a Student in the DB

* @access public

*/

function saveStudent($student)

//Parameter not necessary because our model is named StudentsModelStudents


(used to ilustrate that you can specify an alternative name to the JTable extending class)

//getTable('students'); Here students is not a table name, Table class name

$studentTableRow =& $this->getTable('students');

// Bind the form fields to the student table

if (!$studentTableRow->bind($student)) {

JError::raiseError(500, 'Error binding data');

// Make sure the student record is valid

if (!$studentTableRow->check()) {

JError::raiseError(500, 'Invalid data');

// Insert/update this record in the db

if (!$studentTableRow->store()) {

$errorMessage = $studentTableRow->getError();

JError::raiseError(500, 'Error binding data: '.$errorMessage);

Confidential – All rights reserved. 20


Joomla Component Development .

//If we get here and with no raiseErrors, then everythign went well

/**

* Method that returns an empty student with id 0

* @access public

*/

function getNewStudent(){

//getTable('students'); Here students is not a table name, Table class


name

$studentTableRow =& $this->getTable('students');

$studentTableRow->id = 0;

$studentTableRow->students_uid = 0;

$studentTableRow->students_firstname = '';

$studentTableRow->students_lastname = '';

$studentTableRow->students_grade_id = 0;

$studentTableRow->students_email = '';

$studentTableRow->students_street = '';

$studentTableRow->students_city = '';

$studentTableRow->students_state = '';

$studentTableRow->students_zip = '';

$studentTableRow->students_schoolname = '';

Confidential – All rights reserved. 21


Joomla Component Development .

$studentTableRow->students_schoolstate = '';

$studentTableRow->students_timezone = '';

$studentTableRow->students_gender = '';

$studentTableRow->students_phone1 = '';

$studentTableRow->students_phone2 = '';

$studentTableRow->students_p1_firstname = '';

$studentTableRow->students_p1_lastname = '';

$studentTableRow->students_p1_relationship = '';

$studentTableRow->students_p1_phone1 = '';

$studentTableRow->students_p1_phone2 = '';

$studentTableRow->students_p1_email = '';

$studentTableRow->students_p1_email = '';

$studentTableRow->students_p2_firstname = '';

$studentTableRow->students_p2_lastname = '';

$studentTableRow->students_p2_relationship = '';

$studentTableRow->students_p2_phone1 = '';

$studentTableRow->students_p2_phone2 = '';

$studentTableRow->students_p2_email = '';

$studentTableRow->students_type = 0;

$studentTableRow->students_active =0;

$studentTableRow->students_observedst = 0;

$studentTableRow->studetns_deleted = 0;

$studentTableRow->students_created_on = '';

Confidential – All rights reserved. 22


Joomla Component Development .

$studentTableRow->students_requirements = '';

return $studentTableRow;

function deleteStudents($arrayIDs)

$query = "DELETE FROM #__student WHERE id IN (".implode(',',


$arrayIDs).")";

$db = $this->getDBO();

$db->setQuery($query);

if (!$db->query()){

$errorMessage = $this->getDBO()->getErrorMsg();

JError::raiseError(500, 'Error deleting students: '.$errorMessage);

?>

This code included pagination & filter both we will discuss later.

Confidential – All rights reserved. 23


Joomla Component Development .

Section 3.3 - The view - Listing the students

This view will access the model to get the list of students, then make that list of students
available for the view’s layout/template and then use the JView default display method to
output the html generated by the layout/template.

Note that we will be returning from the model not a list of strings, but a list of objects
created from what was returned from the database. I’ll call those objects row and you’ll
see that each attribute they have corresponds to a database field from the table we’ve
created for our component. The attributes will be id, students_firstname, etc.

The files and classnames for the view:

view file: folder where you’ve installed


joomla/administrator/components/com_students/views/list/view.php

(Remember that the view file is not called view.html.php because we use the getView
method in the controller without specifying its second parameter, the view type).

view class name: StudentsViewList

layout file: folder where you’ve installed


joomla/administrator/components/com_students/views/list/tmpl/listlayout.php

Here’s the view code (list):


<?php
// no direct access
defined( '_JEXEC' ) or die( 'Restricted access' );
jimport( 'joomla.application.component.view');

/**
* HTML View class for the Students Component (List)
*
* @package Students
*/

class StudentsViewList extends JView


{

function display()
{
JToolBarHelper::title('Students Manager', 'generic.png');
JToolBarHelper::deleteList();
JToolBarHelper::editListX();
JToolBarHelper::addNewX();

global $mainframe, $option;

Confidential – All rights reserved. 24


Joomla Component Development .

$db =& JFactory::getDBO();


$uri =& JFactory::getURI();

$filter_state = $mainframe->getUserStateFromRequest(
$option.'filter_state', 'filter_state', '', 'word' );
$filter_active = $mainframe->getUserStateFromRequest(
$option.'filter_active', 'filter_active', 0, 'int' );
$filter_order = $mainframe->getUserStateFromRequest(
$option.'filter_order', 'filter_order', 'a.students_firstname', 'cmd' );
$filter_order_Dir = $mainframe->getUserStateFromRequest(
$option.'filter_order_Dir', 'filter_order_Dir', '', 'word' );
$search = $mainframe->getUserStateFromRequest(
$option.'search', 'search', '', 'string' );
$search = JString::strtolower( $search );

// Get data from the model


$items = & $this->get( 'Data');
$total = & $this->get( 'Total');
$pagination = & $this->get( 'Pagination' );

// build list of active


//$javascript =
'onchange="document.adminForm.submit();"';
//$lists['active'] = JHTML::_('list.active',
'filter_active', $option, intval( $filter_active), $javascript );
// build the active list
$db =& JFactory::getDBO();
$sql = 'SELECT DISTINCT students_active FROM #__student';
$db->setQuery($sql);

$catlist[] = JHTML::_('select.option', '0', JText::_( '-


Select Active -' ), 'id', 'students_active' );
$catlist = array_merge( $catlist, $db->loadObjectList() );
$lists['active'] = JHTML::_('select.genericlist', $catlist,
'active', 'class="inputbox" size="1"
onchange="document.adminForm.submit();"','id', 'students_active',
intval( $filter_active ) );

// state filter
$lists['state'] = JHTML::_('grid.state', $filter_state );

// table ordering
$lists['order_Dir'] = $filter_order_Dir;
$lists['order'] = $filter_order;

// search filter
$lists['search']= $search;

//Push data into the template


$this->assignRef('user', JFactory::getUser());
$this->assignRef('lists', $lists);
$this->assignRef('items', $items);
$this->assignRef('pagination', $pagination);
parent::display();
}
}

Confidential – All rights reserved. 25


Joomla Component Development .

?>

Some new things here: the toolbar code. The first four lines in the display method output
the javascript/html that will make up the toolbar for our component (Figure 1).

Figure 1 – Toolbar

But it is not too hard to use, so don’t worry, the first line (JToolBarHelper::title) sets the
title you’ll see in the toolbar, and the image (generic.png that you can find in folder
where you’ve installed joomla/administrator/images).

The JToolBarHelper::deleteList(), JToolBarHelper::editListX(),


JToolBarHelper::addNewX() add a delete, edit and add buttons to the toolbar. When you
press these buttons some javascript is executed that will eventually submit the form we
will define in layout/template file for this view. There are a few naming conventions used
here that will become clear as soon as I show you an example of the html and javascript
generated for one of those buttons. For example the editListX:

<td class="button" id="toolbar-edit">


<a href="#"
onclick="javascript:if(document.adminForm.boxchecked.value==0){alert('Please
make a selection from the list to edit');}else{ hideMainMenu(); submitbutton('edit')}"
class="toolbar">
<span class="icon-32-edit" title="Edit">
</span>
Edit
</a>
</td>

First, the html form (defined in the layout/template we’ll do next) has to be named
adminForm. This is always true for all forms that you do in the backend. They are
always assumed to be named adminForm.

Some buttons, like the button generated with editListX, assume you have a hidden field
named boxchecked that contains the number of selected items. For example, in our
component, this view we’re doing right now will display a list of students, so boxchecked
will contain the number of students selected (you don’t have to worry about updating
boxchecked, it just has to be defined in the form, and it will be updated automatically. I’ll
tell you how that happens when we see the form in the layout/template file).

Confidential – All rights reserved. 26


Joomla Component Development .

We used editListX (and addNewX), which are alternative versions of editList and
addNew. The difference between them is that the X versions also calls a javascript
function named hideMainMenu that will set the value of a hidden input in the form (if
that input exists) named hidemainmenu to 1. When the form is submitted and if
hidemainmenu is in the request and has a value of 1, joomla makes the administrator
menu (Site Menus Content Components … ) inactive. This is useful when you’re adding
or editing (in our case students) because the user will have to click on one of the buttons
you put in the toolbar (typically Save and Cancel), because all the other buttons will be
inactive.

Finally, the buttons call a joomla javascript function named submitbutton that has one
parameter called pressbutton. For example, when we press the edit button created by the
JToolBarHelper::editListX the submitform will be called with the parameter edit:
submitbutton(‘edit’); What this javascript function does is it sets a hidden field named
task in the adminForm form (in this example with ‘edit’), and then submits the
adminForm. So you see that we also have to have a hidden field named task in our form.

We’ll also have to add a hidden field name option that contains the name of the
component prefixed by “com_”. This is necessary so that when the form is submitted you
get an url equivalent to this (using our component as an example and the edit task):
index.php?option=com_students&task=edit (This is not actually true, because we’ll
POST the form but the important thing here to remember is that joomla needs to know
which component is being executed, hence the option hidden field, and which task is
going to be executed for that component, hence the task hidden field).

So now, you know that we have to do a layout/template for this view with a form named
adminForm and 4 hidden fields named boxchecked, option, task and hidemainmenu. You
also know that we have to list the students, and that there are a few naming conventions
that we’ll have to follow, we’ll see all that next.

Confidential – All rights reserved. 27


DETAIL NOTE 3.3.1:
You can check the code of JToolBarHelper here:
Joomla
folder where you’ve installed Component Development
joomla/administrator/includes/toolbar.php. .

Here’s a list of the most common button generator methods from JToolBarHelper and
what they do to the form (see the toolbar code for all the buttons):
back($alt = 'Back', $href = 'javascript:history.back();') – Generates a button that when
you click on it makes the browser go to the previous page.
addNew($task = 'add', $alt = 'New') – Generates a Add button. (the $alt is the text that
is displayed below the button).
Fields that have to be defined in the form: task.
addNewX($task = 'add', $alt = 'New') same as above. But causes the menu to stay
inactive.
Fields that have to be defined in the form: task, hidemainmenu.
publish($task = 'publish', $alt = 'Publish')
Fields that have to be defined in the form: task.
publishList($task = 'publish', $alt = 'Publish') – Note that the task string used in this
one is the same as the one above.
Fields that have to be defined in the form: task, boxchecked.
unpublish($task = 'unpublish', $alt = 'Unpublish')
Fields that have to be defined in the form: task.
unpublishList($task = 'unpublish', $alt = 'Unpublish')
Fields that have to be defined in the form: task, boxchecked.
editList($task = 'edit', $alt = 'Edit')
Fields that have to be defined in the form: task, boxchecked.
editListX($task = 'edit', $alt = 'Edit')
Fields that have to be defined in the form: task, boxchecked, hidemainmenu.
deleteList($msg = '', $task = 'remove', $alt = 'Delete')- When$msg is not empty, a
confirm box will display the message $msg.
save($task = 'save', $alt = 'Save')
Fields that have to be defined in the form: task.
cancel($task = 'cancel', $alt = 'Cancel')
Fields that have to be defined in the form: task.

DETAIL NOTE 3.3.2:


You can check the joomla javascript (hideMainMenu, submitbutton, submitform) in
here:
folder where you’ve installed joomla/includes/js/joomla.javascript.js

Confidential – All rights reserved. 28


Joomla Component Development .

Here it is: the view’s layout/template. It displays the list of students read from
the DB (Figure 2). The file should be here: folder where you’ve installed
joomla/administrator/components/com_students/views/list/tmpl/listlayout.php

<?php // no direct access


defined('_JEXEC') or die('Restricted access'); ?>
<form action="index.php" method="POST" name="adminForm">
<tr>
<td align="left" width="100%">
<?php echo JText::_( 'Filter' ); ?>:
<input type="text" name="search" id="search" value="<?php
echo $this->lists['search'];?>" class="text_area"
onchange="document.adminForm.submit();" />
<button onclick="this.form.submit();"><?php echo JText::_(
'Go' ); ?></button>
<button
onclick="document.getElementById('search').value='';this.form.getElemen
tById('filter_state').value='';this.form.submit();"><?php echo
JText::_( 'Reset' ); ?></button>
</td>
<td nowrap="nowrap">
<?php
echo $this->lists['state'];
echo $this->lists['active'];
?>
</td>
</tr>

<table class="adminlist">
<thead>
<tr>
<th width="10"><?php echo JText::_( 'NUM' );
?></th>
<th width="10"><input type="checkbox"
name="toggle" value="" onclick="checkAll(<?php echo count($this-
>items); ?>)" /></th>
<th>
<!--First Name-->
<?php echo JHTML::_('grid.sort', 'First
Name', 'a.students_firstname', $this->lists['order_Dir'], $this-
>lists['order'] ); ?>
</th>
<th>
<?php echo JHTML::_('grid.sort', 'Last
Name', 'a.students_lastname', $this->lists['order_Dir'], $this-
>lists['order'] ); ?>
</th>
<th>
<?php echo JHTML::_('grid.sort', 'User
Name', 'a.students_uid', $this->lists['order_Dir'], $this-
>lists['order'] ); ?>
</th>
<th>

Confidential – All rights reserved. 29


Joomla Component Development .

<?php echo JHTML::_('grid.sort', 'Email -


ID', 'a.students_email', $this->lists['order_Dir'], $this-
>lists['order'] ); ?>
</th>
<th>
<?php echo JHTML::_('grid.sort', 'Phone',
'a.students_phone1', $this->lists['order_Dir'], $this-
>lists['order'] ); ?>
</th>
<th>
<?php echo JHTML::_('grid.sort', 'Student
Type', 'a.students_type', $this->lists['order_Dir'], $this-
>lists['order'] ); ?>
</th>
<th>
<?php echo JHTML::_('grid.sort', 'Active',
'a.students_active', $this->lists['order_Dir'], $this-
>lists['order'] ); ?>
</th>
<th>
<?php echo JHTML::_('grid.sort',
'published', 'a.published', $this->lists['order_Dir'], $this-
>lists['order'] ); ?>
</th>
</tr>
</thead>

<tfoot>
<tr>
<td colspan="9">
<?php echo $this->pagination-
>getListFooter(); ?>
</td>
</tr>
</tfoot>
<tbody>
<?php
$k = 0;
for ($i=0, $n=count( $this->items ); $i < $n; $i++)
{
$row = &$this->items[$i];
$link = JRoute::_(
'index.php?option='.JRequest::getVar('option').'&task=edit&cid[]='.
$row->id.'&hidemainmenu=1' );
$checked =
JHTML::_('grid.checkedout', $row, $i );
$published =
JHTML::_('grid.published', $row, $i );
$ordering = ($this->lists['order']
== 'a.ordering');
//$checked = JHTML::_('grid.id',
$i, $row->id);
?>

<tr class="<?php echo "row$k";?>">


<!--<td><?php echo $row->id;?></td>
<td><?php echo $checked; ?></td>

Confidential – All rights reserved. 30


Joomla Component Development .

<td align="center"><a href="<?php


echo $link;?>"><?php echo $row->students_firstname;?></a></td>
<td align="center"><a href="<?php
echo $link;?>"><?php echo $row->students_lastname;?></a></td>
<td align="center"><a href="<?php
echo $link;?>"><?php echo $row->students_uid;?></a></td>
<td align="center"><a href="<?php
echo $link;?>"><?php echo $row->students_email;?></a></td>
<td align="center"><a href="<?php
echo $link;?>"><?php echo $row->students_phone1;?></a></td>
<td align="center"><a href="<?php
echo $link;?>"><?php echo $row->students_type;?></a></td>
<td align="center"><a href="<?php
echo $link;?>"><?php echo $row->students_active;?></a></td>-->
<td>
<?php echo $this-
>pagination->getRowOffset( $i ); ?>
</td>

<td>
<?php echo
$checked; ?>
</td>
<td>
<?php
if
( JTable::isCheckedOut($this->user->get ('id'), $row->checked_out ) ) {
echo $this-
>escape($row->students_firstname);
} else {
?>
<span
class="editlinktip hasTip" title="<?php echo JText::_( 'Edit
Student' );?>::<?php echo $this->escape($row->students_firstname); ?>">
<a href="<?php
echo $link; ?>">
<?php echo $this-
>escape($row->students_firstname); ?></a></span>
<?php
}
?>
</td>
<td>
<?php
if
( JTable::isCheckedOut($this->user->get ('id'), $row->checked_out ) ) {
echo $this-
>escape($row->students_lastname);
} else {
?>
<span
class="editlinktip hasTip" title="<?php echo JText::_( 'Edit
Student' );?>::<?php echo $this->escape($row->students_firstname); ?>">
<a href="<?php
echo $link; ?>">
<?php echo $this-
>escape($row->students_lastname); ?></a></span>

Confidential – All rights reserved. 31


Joomla Component Development .

<?php
}
?>
</td>
<td>
<?php
if
( JTable::isCheckedOut($this->user->get ('id'), $row->checked_out ) ) {
echo $this-
>escape($row->students_uid);
} else {
?>
<span
class="editlinktip hasTip" title="<?php echo JText::_( 'Edit
Student' );?>::<?php echo $this->escape($row->students_firstname); ?>">
<a href="<?php
echo $link; ?>">
<?php echo $this-
>escape($row->students_uid); ?></a></span>
<?php
}
?>
</td>
<td>
<?php
if
( JTable::isCheckedOut($this->user->get ('id'), $row->checked_out ) ) {
echo $this-
>escape($row->students_email);
} else {
?>
<span
class="editlinktip hasTip" title="<?php echo JText::_( 'Edit
Student' );?>::<?php echo $this->escape($row->students_firstname); ?>">
<a href="<?php
echo $link; ?>">
<?php echo $this-
>escape($row->students_email); ?></a></span>
<?php
}
?>
</td>
<td>
<?php
if
( JTable::isCheckedOut($this->user->get ('id'), $row->checked_out ) ) {
echo $this-
>escape($row->students_phone1);
} else {
?>
<span
class="editlinktip hasTip" title="<?php echo JText::_( 'Edit
Student' );?>::<?php echo $this->escape($row->students_firstname); ?>">
<a href="<?php
echo $link; ?>">
<?php echo $this-
>escape($row->students_phone1); ?></a></span>

Confidential – All rights reserved. 32


Joomla Component Development .

<?php
}
?>
</td>
<td>
<?php
if
( JTable::isCheckedOut($this->user->get ('id'), $row->checked_out ) ) {
echo $this-
>escape($row->students_type);
} else {
?>
<span
class="editlinktip hasTip" title="<?php echo JText::_( 'Edit
Student' );?>::<?php echo $this->escape($row->students_firstname); ?>">
<a href="<?php
echo $link; ?>">
<?php echo $this-
>escape($row->students_type); ?></a></span>
<?php
}
?>
</td>
<td>
<?php
if
( JTable::isCheckedOut($this->user->get ('id'), $row->checked_out ) ) {
echo $this-
>escape($row->students_active);
} else {
?>
<span
class="editlinktip hasTip" title="<?php echo JText::_( 'Edit
Student' );?>::<?php echo $this->escape($row->students_firstname); ?>">
<a href="<?php
echo $link; ?>">
<?php echo $this-
>escape($row->students_active); ?></a></span>
<?php
}
?>
</td>
<td>
<?php
if
( JTable::isCheckedOut($this->user->get ('id'), $row->checked_out ) ) {
echo $this-
>escape($row->published);
} else {
?>
<span
class="editlinktip hasTip" title="<?php echo JText::_( 'Edit
Student' );?>::<?php echo $this->escape($row->students_firstname); ?>">
<a href="<?php
echo $link; ?>">
<?php echo $this-
>escape($row->published); ?></a></span>

Confidential – All rights reserved. 33


Joomla Component Development .

<?php
}
?>
</td>

</tr>
<?php
$k = 1 - $k;
//$i++;
}
?>
</tbody>
</table>

<input type="hidden" name="option" value="<?php echo


JRequest::getVar( 'option' );?>"/>
<input type="hidden" name="task" value=""/>
<input type="hidden" name="boxchecked" value="0"/>
<input type="hidden" name="hidemainmenu" value="0"/>
<input type="hidden" name="filter_order" value="<?php echo
$this->lists['order']; ?>" />
<input type="hidden" name="filter_order_Dir" value="<?php echo
$this->lists['order_Dir']; ?>" />
<?php echo JHTML::_( 'form.token' ); ?>
</form>

Figure 2 – List the students

There are a few things you have to know. First, the form action is index.php and the name
of the form has to be adminForm.

The html table’s css class: adminlist is a css class name used in joomla. The css classes
are defined by joomla templates. In this case, because we’re working in the backend, the
adminlist css class is defined in a backend template. I don’t think template details are
very important here, so just trust me about using that css class, and a few more that I’ll
mention. Joomla templates have sufficient material for several tutorials. If you want, have

Confidential – All rights reserved. 34


Joomla Component Development .

a look at the css from the default template for the backend that comes with joomla 1.5
(named khepri), the css is in folder where you’ve installed
jooma/administrator/templates/khepri/css, the files that define the class adminlist are
general.css and general_rt.css.

The table header will display something like this: # [checkbox] First Name (Figure 2).
There are a few things you need to know about that checkbox. Its behaviour is that when
you click on it, you select/deselect all items (in our case students). This will work if we
respect joomla’s naming conventions for the checkboxes. First, this checkbox has to be
named toggle, and it’s onclick event handler has to be checkAll([Number of items listed])
(in our case, the number of items are the students). The checkAll javascript method is
defined in folder where you’ve installed joomla/includes/js/joomla.javascript.js, and what
it does is that it checks to see if a checkbox named toggle inside a form named
adminForm is checked or not, and then it goes through the checkboxes with id cbX,
where X goes from 0 to the number you pass as argument to checkAll-1, and checks or
unchecks them depending on the of checkbox named toggle being checked or not. So
now you know that the checkboxes to select each individual item have to have an id: cb0,
cb1, cb2, etc. But fortunately, since joomla 1.5, you don’t have to worry about that
because the code: JHTML::_('grid.id', $i, $row->id); generates that for you. JHTML is
used to generate the html for several html elements

DETAIL NOTE 3.3.3: If you see the actual HTML generated when you do
JHTML::_('grid.id', $i, $row->id); you’ll see that the name of the checkboxes is
actually cid[]. This is a php thing: when you add ‘[]’ to the name of a checkbox and
you have several checkboxes with that same name followed by ‘[]’ you can read an
array from the request with the value of the checked checkboxes. In our case, when we
read cid from the request we’ll get an array that contains the values of the checked
checkboxes.

Each of the students displayed is a link, that when you click on it redirects you to the url:
index.php?option=com_students&task=edit&cid[]=ID_OF_THE_ROW_WE_WANT_TO
_EDIT&hidemainmenu=1. We’re using JRoute’s ‘_’ function to build the url. We should
do that because the ‘_’ method from JRoute rewrites the url to a Search Engine
Friendly(SEF) form if SEF is enabled in Joomla (To enable SEF go to Site->Global
Configuration). However, SEF doesn’t work on the backend so you won’t see any
difference in the url, but still it’s good practice to use it because if you want to reuse some
of the code in the frontend you won’t have to worry about the urls .The hidemainmenu
parameter is set to 1 in the url so that the joomla’s administrator menu stays disabled
when editing (remember, that also happens when we click the edit button because we use
JToolBar::editListX : the X version of editList).

Confidential – All rights reserved. 35


Joomla Component Development .

About the actual listing of the students (the foreach’s code), we’re using a trick to change
the css class of every <TR>. The css classes row0 and row1 have different background
colors making it easier for you to distinguish between each item in the list (in our case,
each student). The rest is each table row displays the student’s id, followed by a checkbox
that was generated by JHTML::_('grid.id', $i, $row->id); and then the actual student, in
the form of a link that, when pressed will create a request for our backend’s component
with the task edit and with the parameter cid (that will be an array) with the value of the
id of the student we want to edit (we still have to code the edit task).

DETAIL NOTE 3.3.4: This note is about how the boxchecked hidden field is updated.
The code generated by JHTML::_('grid.id', $i, $row->id); is something like this:
<input id="cb0" name="cid[]" value="1" onclick="isChecked(this.checked);"
type="checkbox"> . The javascript isChecked method is the one that updated
boxchecked hidden input field. What it does is if the checkbox is being checked it adds
1 to the boxchecked adminForm’s hidden input, if it is being unchecked it subtracts 1.
You can see the code for isChecked here: folder where you’ve installed
joomla/includes/js/joomla.javascript.js.

Confidential – All rights reserved. 36


Joomla Component Development .

Section 4 – The backend tasks – The edit task


Section 4.1 – The controller task: edit

Now let’s do the edit task. To do that we just have to add a method named edit to our
controller that will load a view named studentForm, with a layout/template named
studentformlayout. We will use the same model we used for listing the students although
we’ll add a new method that will return an object that represents a row in the students
table in the database (we’ll look at that in Section 4.2). I’m not reading the viewname
and layout from the request in this task, I just make the view name and layout fixed to
studentForm and studentformlayout respectively.

In this task we’ll read the id of the student we want to edit. There is a detail about reading
the id from the request. Remember that when we listed the student we put a link in each
one: index.php?option=com_student&task=edit&cid[]=ID. Where ID is the actual ID for
the student we want to edit. You might be asking yourself right now why did I used cid[]
as a parameter. Especially because if we’re just editing one student, why do we need to
put it in an array? The answer to that is: it’s because of the Edit button in the toolbar.
When you click on it, it submits the form that has the list of student, and the selected
students will go in the request in the cid[] parameter. So, that’s why we called the
parameter with the id of the student cid[] , so that we could handle both cases (clicking
on the link and clicking the edit button in the toolbar) the same way.

We’ll call a method named displayEdit in the view and pass the id of the student as a
parameter to it (we’ll do the view’s displayEdit method in Section 4.3).

Remember that our controller file is named studentsController.php, and it should be


located in folder where you’ve installed
joomla/administrator/components/com_students/studentsController.php.

Code for edit method:


function edit(){
//getVar(PARAMETER_NAME, DEFAULT_VALUE, HASH, TYPE)
//The HASH is where to read the parameter from:
//The default is its default value: getVar will look for the parameter in
//GET, then POST and then FILE
$cids = JRequest::getVar('cid', null, 'default', 'array' ); //Reads cid as an array

if($cids === null){ //Make sure the cid parameter was in the request
JError::raiseError(500, 'cid parameter missing from the request');
}

$studentId = (int)$cids[0]; //get the first id from the list (we can only edit one student at a time)

$view = & $this->getView('studentForm');

// Get/Create the model


if ($model = & $this->getModel('students')) {
//Push the model into the view (as default)

Confidential – All rights reserved. 37


Joomla Component Development .

//Second parameter indicates that it is the default model for the view
$view->setModel($model, true);
}

$view->setLayout('studentformlayout');
$view->displayEdit($studentId);
}

Section 4.2 The model – Getting a student through its id

We have to add a method to our model that gets a student from the database based on its
id. If you remember the code that we did for the default task (display) that displays a list
of the students read from the database, you’ll remember that in that list each student has a
link. Something like this: index.php?option=com_students&task=edit&cid[]=1. Where,
in this example the 1 is the id of the student we want to edit. So our new method for the
model will do just that: get the student from the database with a specific id. Let’s call that
method getStudent.

Remember that our model file is named students.php and that it is located in folder where
you’ve installed joomla/administrator/components/com_students/models/students.php

Here’s the code getStudents() method:

function getStudent($id){
$query = 'SELECT * FROM #__student'.
' WHERE id = '.$id;
$db = $this->getDBO();
$db->setQuery($query);
$student = $db->loadObject();

if ($student === null)


JError::raiseError(500, 'Student with ID: '.$id.' not found.');
else
return $student;

Section 4.3 The view – form to edit the student

Confidential – All rights reserved. 38


Joomla Component Development .

This view we’re about to do will display a form that will allow us to edit a student
(Figure 3) . We’ll create a method named displayEdit that gets as a parameter the id of the
student we want to edit, then we use the getStudent method from the model associated
with this view to get the actual student from the database and then display it in the form
in the layout/template.

This view will have two buttons on its toolbar: Save and Cancel.

This view will have to be located in: folder where you’ve installed
joomla/administrator/components/com_students/views/studentForm/view.php

The view’s class name is: StudentsViewStudentForm

And the layout/template file:


joomla/administrator/components/com_students/views/studentForm/tmpl/studentformlay
out.php

Here’s the code for the view:

<?php
// no direct access
defined( '_JEXEC' ) or die( 'Restricted access' );
jimport( 'joomla.application.component.view');
/**
* HTML View class for the backend of the Students Component edit task
* @package Students
*/
class StudentsViewStudentForm extends JView
{
function displayEdit($studentId)
{
JToolBarHelper::title('Student'.': [<small>Edit</small>]');
JToolBarHelper::save();
JToolBarHelper::cancel();

$model = $this->getModel();
$student = $model->getStudent($studentId);
$this->assignRef('student', $student);

parent::display();
}

function displayAdd(){
JToolBarHelper::title('Student'.': [<small>Add</small>]');
JToolBarHelper::save();
JToolBarHelper::cancel();

$model = $this->getModel();
$student = $model->getNewStudent();
$this->assignRef('student', $student);

parent::display();

Confidential – All rights reserved. 39


Joomla Component Development .

}
}
?>

Remember that the layout/template for this view is named studentformlayout and should
be located in: folder where you’ve installed
joomla/administrator/com_students/views/studentForm/tmpl/studentformlayout.php

The code is here:

<?php // no direct access


defined('_JEXEC') or die('Restricted access'); ?>
<form action="index.php" method="POST" name="adminForm" id="adminForm">
<fieldset class="adminform">
<legend>Student Details</legend>
<table class="admintable">
<tr>
<td class="key">First Name *</td>
<td>
<input type="text" name="students_firstname" id="students_firstname"
size="32" maxlength="250" value="<?php echo $this->student->students_firstname; ?>" />
</td>

</tr>
<tr>
<td class="key">Last Name *</td>
<td>
<input type="text" name="students_lastname" id="students_lastname"
size="32" maxlength="250" value="<?php echo $this->student->students_lastname; ?>" />
</td>

</tr>
<tr>
<td class="key">Gender *</td>
<td>
<input type="text" name="students_gender" id="students_gender" size="32"
maxlength="250" value="<?php echo $this->student->students_gender; ?>" />
</td>

</tr>
<tr>
<td class="key">Email ID *</td>
<td>
<input type="text" name="students_email" id="students_email" size="32"
maxlength="250" value="<?php echo $this->student->students_email; ?>" />
</td>

</tr>
<tr>
<td class="key">Street</td>
<td>
<input type="text" name="students_street" id="students_street" size="32"
maxlength="250" value="<?php echo $this->student->students_street; ?>" />
</td>

Confidential – All rights reserved. 40


Joomla Component Development .

</tr>
<tr>
<td class="key">City</td>
<td>
<input type="text" name="students_city" id="students_city" size="32"
maxlength="250" value="<?php echo $this->student->students_city; ?>" />
</td>

</tr>
<tr>
<td class="key">State</td>
<td>
<input type="text" name="students_state" id="students_state" size="32"
maxlength="250" value="<?php echo $this->student->students_state; ?>" />
</td>

</tr>
<tr>
<td class="key">ZIP</td>
<td>
<input type="text" name="students_zip" id="students_zip" size="32"
maxlength="250" value="<?php echo $this->student->students_zip; ?>" />
</td>

</tr>
<tr>
<td class="key">School State *</td>
<td>
<input type="text" name="students_schoolstate" id="students_schoolstate"
size="32" maxlength="250" value="<?php echo $this->student->students_schoolstate; ?>" />
</td>

</tr>
<tr>
<td class="key">Phone 1</td>
<td>
<input type="text" name="students_phone1" id="students_phone1"
size="32" maxlength="250" value="<?php echo $this->student->students_phone1; ?>" />
</td>

</tr>
<tr>
<td class="key">Phone 2</td>
<td>
<input type="text" name="students_phone2" id="students_phone2"
size="32" maxlength="250" value="<?php echo $this->student->students_phone2; ?>" />
</td>

</tr>
<tr>
<td class="key">Time Zone *</td>
<td>
<input type="text" name="students_timezone" id="students_timezone"
size="32" maxlength="250" value="<?php echo $this->student->students_timezone; ?>" />
</td>

Confidential – All rights reserved. 41


Joomla Component Development .

</tr>
<tr>
<td class="key">Student Type</td>
<td>
<input type="text" name="students_type" id="students_type" size="32"
maxlength="250" value="<?php echo $this->student->students_type; ?>" />
</td>

</tr>
<tr>
<td class="key">Status</td>
<td>
<input type="text" name="students_active" id="students_active" size="32"
maxlength="250" value="<?php echo $this->student->students_active; ?>" />
</td>

</tr>
</table>
<legend>Parent/Guardian</legend>
<table class="admintable">
<tr>
<td class="key">First Name *</td>
<td>
<input type="text" name="students_p1_firstname"
id="students_p1_firstname" size="32" maxlength="250" value="<?php echo $this->student-
>students_p1_firstname; ?>" />
</td>

</tr>
<tr>
<td class="key">Last Name *</td>
<td>
<input type="text" name="students_p1_lastname"
id="students_p1_lastname" size="32" maxlength="250" value="<?php echo $this->student-
>students_p1_lastname; ?>" />
</td>

</tr>
<tr>
<td class="key">Relationship</td>
<td>
<input type="text" name="students_p1_relationship"
id="students_p1_relationship" size="32" maxlength="250" value="<?php echo $this->student-
>students_p1_relationship; ?>" />
</td>

</tr>
<tr>
<td class="key">Phone 1 *</td>
<td>
<input type="text" name="students_p1_phone1" id="students_p1_phone1"
size="32" maxlength="250" value="<?php echo $this->student->students_p1_phone1; ?>" />
</td>

</tr>

Confidential – All rights reserved. 42


Joomla Component Development .

<tr>
<td class="key">Phone 2</td>
<td>
<input type="text" name="students_p1_phone2" id="students_p1_phone2"
size="32" maxlength="250" value="<?php echo $this->student->students_p1_phone2; ?>" />
</td>

</tr>
<tr>
<td class="key">Email Address *</td>
<td>
<input type="text" name="students_p1_email" id="students_p1_email"
size="32" maxlength="250" value="<?php echo $this->student->students_p1_email; ?>" />
</td>

</tr>
</table>
</fieldset>

<input type="hidden" name="option" value="<?php echo JRequest::getVar( 'option' );?>"/>


<input type="hidden" name="id" value="<?php echo $this->student->id; ?>"/>
<input type="hidden" name="task" value=""/>
</form>

Figure – 3 The Edit Form

Confidential – All rights reserved. 43


Joomla Component Development .

Remember that we used the Save and Cancel buttons in the toolbar, the Save button
causes this form to be submitted with the hidden field task with value ‘save’ and the
Cancel button submits the form with the hidden field task with value ‘cancel’.

There is an important detail here, which is: the form has to have inputs with the same
name as the fields in our jos_students table, that’s why there is a hidden field named id.
When we do the save task it will be clear why.

Confidential – All rights reserved. 44


Joomla Component Development .

Confidential – All rights reserved. 45


Joomla Component Development .

Section 5: The backend tasks - Save


Section 5.1 – The controller task: save

When we edit a student and click on the save button the form we just did before is going
to be submitted with the task parameter set to save. That will cause the save task to be
executed in the controller. So we need to do the method to handle that task, and that
method has to be named save.

So let’s add that method to our backend controller, it will read the data posted by the form
we did for the studentForm view. Then it will use a method in the model that will get that
post data as a parameter and will use it to update the database record that corresponds to
the student we’re editing (we need to add that method to our model, it is named
saveStudent).

Finally, after using the model to save the edited student we’ll use the JController’s
method setRedirect to make joomla redirect to the page where the students are listed (our
components default task, display).

DETAIL NOTE 5.1.1: If you’re wondering how setRedirect will redirect you to the
link you pass as a parameter look at our entry point file, and you’ll see that at the end a
method named redirect from the controller is executed. That method is what actually
causes the browser to redirect to the link we supply as a parameter to setRedirect.

We are editing controller file, located in: folder where you’ve installed
joomla/administrator/com_student/studentsController.php

Here’s the code (save() method in studentsController.php):


function save(){
$student = JRequest::get( 'POST' );
$model = & $this->getModel('students');
$model->saveStudent($student);

$redirectTo = JRoute::_('index.php?option='.JRequest::getVar('option').'&task=display');
$this->setRedirect($redirectTo, 'Student Saved!');

Here is the Code (saveStudent($student) method in …


/models/students.php)
/**
* Method to store a student in the DB
*/
function saveStudent($student)

Confidential – All rights reserved. 46


Joomla Component Development .

{
//Parameter not necessary because our model is named StudentsModelStudents (used
to illustrate that you can specify an alternative name to the JTable extending class)
//getTable('students'); Here students is not a table name, Table class name

$studentTableRow =& $this->getTable('students');

// Bind the form fields to the student table


if (!$studentTableRow->bind($student)) {
JError::raiseError(500, 'Error binding data');
}

// Make sure the student record is valid


if (!$studentTableRow->check()) {
JError::raiseError(500, 'Invalid data');
}

// Insert/update this record in the db


if (!$studentTableRow->store()) {
$errorMessage = $studentTableRow->getError();
JError::raiseError(500, 'Error binding data: '.$errorMessage);
}
}

Confidential – All rights reserved. 47


Joomla Component Development .

Section 5.2 JTABLE

To have our saveStudent method in the model we’re going to use an instance of a class
we’ll do that extends JTABLE. JTABLE is a class we can extend that has methods that
help us interact with the database, especially if we want to update or add records to a
database table.

To use the functionalities that JTABLE has we have to create a class that extends JTABLE
and has a direct correspondence between the names of its attributes and the names of the
fields in the database table we’re dealing with. Using our jos_students table as an
example, the class that we’re going to write that extends JTABLE has many attributes, for
example named id, students_firstname,students_lastname, etc., which correspond to the
jos_students database table fields with the same name. We also have to specify in the
constructor which of the fields is the key for the database and also the table’s name.

The JModel specifies methods to get instances of JTABLE following some naming
conventions. First, the default location for JTABLE files is, in the backend: folder where
you’ve installed joomla/admistrator/components/com_students/tables; in the frontend it’s
the same without administrator (you can change the default location in the model’s
constructor).

You can use a JModel’s method named getTable without parameters to get the class that
extends JTABLE following JModel’s naming conventions for table classes.

The convention is:

• The class extending JTABLE should be named Table[ModelName], where


[ModelName] is the model’s name from where we’re using the JModel’s gettable
method without parameters. Remember that the model’s class name is build by:
[ControllerName]Model[ModelName].
• The class that extends JTable should be located in folder where you’ve installed
joomla/administrator/components/[COMPONENT_NAME]/tables where
[COMPONENT_NAME] is the name of the component where our model is. And
should be named [ModelName].php (the file name has to be in lowercase).

If you want, you can specify a name in the JModel’s getTable method, for example
getTable(‘Mytable’), this tries to get an instance for a class named TableMyTable located
in joomla/administrator/components/[COMPONENT_NAME]/tables/mytable.php for the
backend (the same for the frontend without administrator.)

Confidential – All rights reserved. 48


Joomla Component Development .

DETAIL NOTE 5.2.1: To change the default location of the classes that extend
JTable you have to override the default constructor ofthe model class you’re using,
and specify in the config array, that the constructor gets as argument, a parameter
named table_path. For example, if we want to change the tables folder in our model
for the students (in the backend) we would add this code to our model file located in:

folder where you’ve installed


joomla/administrator/components/com_students/models/students.php

function __construct(){
parent::__construct(array('table_path'=>JPATH_COMPONENT.DS.'myTablesFolder')
);
}

Here’s the code for the class that will extend JTable that we will be using to add and
update students in our students’ database table, it has to be located in:

folder where you’ve installed joomla/administrator/components/com_students/tables

and the file will be named students.php:

<?php
defined('_JEXEC') or die('Restricted Access');
class TableStudents extends JTable {
public $id = null;
public $students_firstname = null;
public $students_lastname = null;
public $students_email = null;
public $students_street = null;
public $students_city = null;
public $students_state = null;
public $students_zip = null;
public $students_schoolstate = null;
public $students_timezone = null;
public $students_gender = null;
public $students_phone1 = null;
public $students_phone2 = null;
public $students_p1_firstname = null;
public $students_p1_lastname = null;
public $students_p1_relationship = null;
public $students_p1_phone1 = null;
public $students_p1_phone2 = null;
public $students_p1_email = null;
public $students_type = null;
public $students_active =null;

function TableStudents(&$db){
parent::__construct('#__student', 'id', $db);
}

Confidential – All rights reserved. 49


Joomla Component Development .

?>

Section 5.3 The Model – Adding the save functionality

We’re adding a new method to our model named saveStudent that, if you remember from
the controller’s code, we’re invoking there and passing a parameter to it with the data
we’re getting from the request (that will contain the values from the inputs of the from
that is outputted by the studentForm view).

This is where we’ll use the functionalities offered by JTable. I’ll show you the code and
then talk a little bit about the methods we’re using from JTable.

Remember, this file is located in:

folder where you’ve installed joomla/administrator/com_students/models/students.php

Here is the Code (saveStudent($student) method in …


/models/students.php)
/**
* Method to store a student in the DB
*/
function saveStudent($student)
{
//Parameter not necessary because our model is named StudentsModelStudents (used
to illustrate that you can specify an alternative name to the JTable extending class)
//getTable('students'); Here students is not a table name, Table class name

$studentTableRow =& $this->getTable('students');

// Bind the form fields to the student table


if (!$studentTableRow->bind($student)) {
JError::raiseError(500, 'Error binding data');
}

// Make sure the student record is valid


if (!$studentTableRow->check()) {
JError::raiseError(500, 'Invalid data');
}

// Insert/update this record in the db


if (!$studentTableRow->store()) {
$errorMessage = $studentTableRow->getError();
JError::raiseError(500, 'Error binding data: '.$errorMessage);
}
}

Confidential – All rights reserved. 50


Joomla Component Development .

The $student parameter will be an array that will contain the values from the input fields
from the form (that we did in the studentForm view) indexed by the names of the inputs.

The JTable’s bind method we’re using ($studentTableRow->bind($student)) uses


reflection to get all the attributes from the class, and then sets them with the values from
the array passed as a parameter that have a key with the same name as the attributes in the
class. This gets really simple with an example. Imagine our TableStudents class that
extends JTable. It has mnay attributes: id, students_firstname, students_lastname, etc.,.
And remember that the form from the studentForm view has among other form inputs, an
input named id and student. What bind does is it sets the attribute id with the value from
the form input id, and the same for student.

DETAIL 5.3.1: Doc. page for JTable::bind:

http://dev.joomla.org/component/option,com_jd-
wiki/Itemid,/id,references:joomla.framework:table:jtable-bind/

If you look at bind’s signature: boolean bind ( $from, $ignore ) you’ll notice that it has a
second parameter. What it’s for is to specify a list of attributes to be ignored in the
binding process. If for some reason you have attributes in your table class that you don’t
want to update with the values from $from, you put them in $ignore.

Also note that if an attribute is in the table class, but not in $from, no error is produced
and bind still returns true.

After the bind we do the check. What the JTable’s check method does is … well it just
returns true. I just put it there so I could tell you about it. The idea behind the check
method is that you should override it when you extend JTable, and make it return true if
the attributes are valid and false otherwise

Finally, we store. What store does is it inserts a new record in the database if the attribute
that represents the table key is 0 (in our case if the Tablestudent id attribute is 0 a new
record is inserted), or it updates the record whose primary key has the same value as the
value of the attribute we specify as key in the JTable’s class constructor (in our case,
TableStudent id attribute with value X not 0, will cause an update to the student with id
X).

Confidential – All rights reserved. 51


Joomla Component Development .

Section 6: The backend tasks – The add task


Section 6.1: The controller task: add

For the add task we’re doing something very similar to the edit task. This is the task that
will be executed when you click on the toolbar’s Add button when our component is
displaying the list of students (default display task).

What we will do in the controller code is we will add a method named add that will get
the model named students and the view named studentForm and call a method from that
view named disaplyAdd that we’ll do later.

We need to add method to our controller file located in folder where you’ve installed
joomla/administrator/com_students/studentsController.php

Here’s the add() function in controller code:


function add(){
$view = & $this->getView('studentForm');
$model = & $this->getModel('students');

if (!$model){
JError::raiseError(500, 'Model named students not found');
}
$view->setModel($model, true);
$view->setLayout('studentformlayout');
$view->displayAdd();
}

Now let’s do add the displayAdd method to the view named studentForm.

Section 6.2: The view - Form to edit the student (revisited)

We have to add a method named displayAdd that has no arguments to the view named
studentForm.

What this method will do is, it will call a method from the model named getNewStudent
(that we’ll do later) that returns an “empty” student with id 0, and then it’s the same thing
as we did for editing a student. The only difference is that we will be editing a student
with id 0, and the actual student will be an empty string.

We’re editing the view named studentForm which is located here:

Confidential – All rights reserved. 52


Joomla Component Development .

folder where you’ve installed


joomla/administrator/components/com_students/views/studentForm/view.php

Here’s the displayAdd() method in view.php code:


function displayAdd(){
JToolBarHelper::title('Student'.': [<small>Add</small>]');
JToolBarHelper::save();
JToolBarHelper::cancel();

$model = $this->getModel();
$student = $model->getNewStudent();
$this->assignRef('student', $student);

parent::display();
}

That’s it for the view, now let’s do the model.

Section 6.3: The model – New students

We have to add the getNewStudent method to the students model. What this method will
do is it will get an instance form the table class (the one that implements JTBALE) and
set that instance’s id attribute to 0 and the student attribute to the empty string.

We’re editing the students model file located in: folder where you’ve installed
joomla/administrator/components/com_students/models/students.php

Here’s the getNewStudent() ..//models/students.php code:


/**
* Method that returns an empty student with id 0
*/
function getNewStudent(){

//getTable('students'); Here students is not a table name, Table class name


$studentTableRow =& $this->getTable('students');
$studentTableRow->id = 0;
$studentTableRow->students_uid = 0;
$studentTableRow->students_firstname = '';
$studentTableRow->students_lastname = '';
$studentTableRow->students_grade_id = 0;
$studentTableRow->students_email = '';
$studentTableRow->students_street = '';
$studentTableRow->students_city = '';
$studentTableRow->students_state = '';
$studentTableRow->students_zip = '';
$studentTableRow->students_schoolname = '';
$studentTableRow->students_schoolstate = '';
$studentTableRow->students_timezone = '';

Confidential – All rights reserved. 53


Joomla Component Development .

$studentTableRow->students_gender = '';
$studentTableRow->students_phone1 = '';
$studentTableRow->students_phone2 = '';
$studentTableRow->students_p1_firstname = '';
$studentTableRow->students_p1_lastname = '';
$studentTableRow->students_p1_relationship = '';
$studentTableRow->students_p1_phone1 = '';
$studentTableRow->students_p1_phone2 = '';
$studentTableRow->students_p1_email = '';
$studentTableRow->students_p1_email = '';
$studentTableRow->students_p2_firstname = '';
$studentTableRow->students_p2_lastname = '';
$studentTableRow->students_p2_relationship = '';
$studentTableRow->students_p2_phone1 = '';
$studentTableRow->students_p2_phone2 = '';
$studentTableRow->students_p2_email = '';
$studentTableRow->students_type = 0;
$studentTableRow->students_active =0;
$studentTableRow->students_observedst = 0;
$studentTableRow->studetns_deleted = 0;
$studentTableRow->students_created_on = '';
$studentTableRow->students_requirements = '';

return $studentTableRow;
}

Why are we doing this? Remember when I explained how the JTable’s store method
worked? That when the attribute associated with the table’s primary key was 0 the store
method would insert a new record in the database. That’s what happening here, it is like
you’re editing a student with id 0, but when you click the save button, and the save task is
executed, you get a new record in the database.

Confidential – All rights reserved. 54


Joomla Component Development .

Section 7: The backend tasks: The remove task


Section 7.1: The controller task: remove

To do the remove task we have to get the id of the student we want to remove (like we did
for the student to edit, in the edit task). Then we’ll call a method from the model named
deleteStudents to which we will supply the array with the ids of the student as a
parameter (we’ll do deleteStudents later), and then use the JController’s setRedirect
method to redirect to the list of the students.

We’re editing the controller’s class located in:

folder where you’ve installed joomla/administrator/com_students/studentsController.php

Here is remove() method code in studentsController.php


function remove(){
$arrayIDs = JRequest::getVar('cid', null, 'default', 'array' ); //Reads cid as an array

if($arrayIDs === null){ //Make sure the cid parameter was in the request
JError::raiseError(500, 'cid parameter missing from the request');
}

$model = & $this->getModel('students');


$model->deleteStudents($arrayIDs);

$redirectTo = JRoute::_('index.php?option='.JRequest::getVar('option'));
$this->setRedirect($redirectTo, 'Deleted...');
}

Section 7.2: The model – Deleting students

Where doing the deleteStudents method in our students model that gets an array with the
id’s of the students to be deleted as input.

We’re using php’s implode method that has two arguments, the separator and the array.
Imagine you use implode with arguments (‘,’, array(‘a’,’b’,’c’)) you’d get a string like
this: ‘a,b,c’.

We’re editing the model named students’ file, located in:

folder where you’ve installed joomla/administrator/com_students/models/students.php

Here is the deleteStudents() in ..//models/students.php


function deleteStudents($arrayIDs)
{
$query = "DELETE FROM #__student WHERE id IN (".implode(',', $arrayIDs).")";

Confidential – All rights reserved. 55


Joomla Component Development .

$db = $this->getDBO();
$db->setQuery($query);
if (!$db->query()){
$errorMessage = $this->getDBO()->getErrorMsg();
JError::raiseError(500, 'Error deleting students: '.$errorMessage);
}
}

Note that we’re using the getErrorMsg method from JDatabase to get the error message.
If there’s an error while the query is being executed (query method) getErrorMsg returns
the SQL error that describes what happened.

Confidential – All rights reserved. 56


Joomla Component Development .

Confidential – All rights reserved. 57


Joomla Component Development .

Section 8: Download & Installation


http://cid-
e9dd1034313be3eb.skydrive.live.com/browse.aspx/Joomla?authkey=gjPSvFj48xQ%
24

Use this link to download student_component.

Unzip Student_Component.

You will find:

• Com_students (component)
• Joomla_Component_Development .doc (Document)
• jos_components.sql (sql query)
• jos_Students.sql (sql query)

Place com_students folder in joomla path ..\\administrator\components\

Execute jos_components.sql and jos_Students.sql on mysql joomla database.

That’s it.

TEST:

Login to Joomla. Click on component. Find ‘Manage Student’ link. Click on this &
Explore.

If you have any queries, please free to mail me.


(mailto:prabhu.patil@reachwell.net?subject=Joomla Queries)

Thank you,

Prabhu Patil

Confidential – All rights reserved. 58

You might also like