Developing A MVC Component
Developing A MVC Component
22
DevelopingaMVCComponent
Contents.................................................................................................................................................22
Introduction...........................................................................................................................................22
Contents
DevelopingaMVCComponent/DevelopingaBasicComponent.................................................................5
DevelopingaMVCComponent/Usingthedatabase..................................................................................26
Contents...................................................................................................................................................5
Contents.................................................................................................................................................26
Public display......................................................................................................................................6
Introduction...........................................................................................................................................26
Administrator management...............................................................................................................6
DevelopingaMVCComponent/Addingaviewtothesitepart....................................................................8
Contents...................................................................................................................................................9
DevelopingaMVCComponent/Basicbackend..........................................................................................33
Introduction.............................................................................................................................................9
Contents.................................................................................................................................................34
Introduction...........................................................................................................................................34
Basic backend........................................................................................................................................34
DevelopingaMVCComponent/Addingamenutypetothesitepart........................................................14
Contents.................................................................................................................................................14
Introduction...........................................................................................................................................14
Abstract..................................................................................................................................................15
DevelopingaMVCComponent/Addinglanguagemanagement................................................................41
Contents.................................................................................................................................................41
DevelopingaMVCComponent/Addingamodeltothesitepart...............................................................17
Introduction...........................................................................................................................................42
Contents.................................................................................................................................................18
Introduction...........................................................................................................................................18
Adding a model.....................................................................................................................................18
DevelopingaMVCComponent/Addingavariablerequestinthemenutype...........................................22
DevelopingaMVCComponent/Addingbackendactions...........................................................................47
Contents.................................................................................................................................................48
Introduction...........................................................................................................................................48
Adding a toolbar...................................................................................................................................48
DevelopingaMVCComponent/Addingconfiguration...............................................................................86
Contents.................................................................................................................................................86
Introduction...........................................................................................................................................86
DevelopingaMVCComponent/Addingdecorationstothebackend.........................................................58
Contents.................................................................................................................................................58
Introduction...........................................................................................................................................58
DevelopingaMVCComponent/AddingACL.............................................................................................100
Contents...............................................................................................................................................100
DevelopingaMVCComponent/Addingverifications.................................................................................65
Introduction.........................................................................................................................................101
Contents.................................................................................................................................................66
Introduction...........................................................................................................................................66
Add the 'Options' toolbar button when user is authorised for it................................................103
DevelopingaMVCComponent/Addingcategories....................................................................................76
Contents.................................................................................................................................................76
Introduction...........................................................................................................................................76
Public display
Contents...............................................................................................................................................121
Introduction.........................................................................................................................................121
Hello world
Administrator management
Contents
If you have used Joomla before reading this tutorial, you have noticed that extensions are
installed using a compressed file containing all the things which are needed for installing and
uninstalling them.
With your favorite file manager, create a directory (outside your Joomla installation directory)
containing
[Expand]
helloworld.xml
site/helloworld.php
site/index.html
admin/index.html
admin/helloworld.php
admin/sql/index.html
admin/sql/updates/index.html
admin/sql/updates/mysql/index.html
6
admin/sql/updates/mysql/0.0.1.sql
Create a compressed file of this directory or directly download the archive and install it using the
extension manager of Joomla. You can test this basic component by putting
index.php?option=com_helloworld or administrator/index.php?option=com_helloworld in your
browser address. You can also notice that the Hello World! component is visible in the
administrator site of your Joomla installation under the Components menu.
<administration>
<!-- Administration Menu Section -->
<menu>Hello World!</menu>
<!-- Administration Main File Copy Section -->
<!-- Note the folder attribute: This attribute describes the
folder
to copy FROM in the package to install therefore
files copied
in this section are copied from /admin/ in the
Note: <name>Hello World!</name> is tricking you into thinking that this is actually only a
name, and you could call it 'fluffy' or 'bippo', but this is not true. As far as I understand the name
in between the tags is getting automagically lowercased, white spaces and special characters are
removed (the ! for example) and joomla starts to look for files/folders responding to this name.
So the name you are giving there is actually very crucial for your component to work. In other
words, if you would change "Hello World!" to "helloworld" everyhting would still work. If you
would change it to "helloworld2" the component would be looking for different folders and file
names.
package -->
<files folder="admin">
<!-- Admin Main File Copy Section -->
<filename>index.html</filename>
<filename>helloworld.php</filename>
<!-- SQL files section -->
<folder>sql</folder>
</files>
</administration>
</extension>
helloworld.xml
site/helloworld.php
<?xml version="1.0" encoding="utf-8"?>
<extension type="component" version="2.5.0" method="upgrade">
Hello World
<name>Hello World!</name>
<!-- The following elements are optional and free of formatting
constraints -->
<creationDate>November 2009</creationDate>
<author>John Doe</author>
<authorEmail>[email protected]</authorEmail>
<authorUrl>http://www.example.org</authorUrl>
<copyright>Copyright Info</copyright>
<license>License Info</license>
<!-- The version string is recorded in the components table -->
<version>0.0.1</version>
<!-- The description is optional and defaults to the name -->
<description>Description of the Hello World component
...</description>
admin/helloworld.php
Contents
1 Introduction
2 Setting the controller
3 Setting the view
4 Packaging the component
5 Navigate
6 Contributors
The getInstance static method of the JController class will create a controller. In the code above,
it will instantiate a controller object of a class named HelloWorldController. Joomla will look for
the declaration of that class in an aptly named file called controller.php (it's a default behavior).
[Expand]
Introduction
<?php
// No direct access to this file
defined('_JEXEC') or die('Restricted access');
In the Joomla!2.5 framework, third party component authors divide their code into three main
parts:
/**
* Hello World Component Controller
*/
class HelloWorldController extends JController
{
}
When no task is given in the request variables, the default task will be executed. It's the display
task by default. The JController class has such a task. In our example, it will display a view
named HelloWorld.
In the core code of Joomla, there is a class able to manage controllers: JController. This class
has to be extended to be used in our component. In the file site/helloworld.php (entry point of
our Hello World component), put these lines
site/helloworld.php
A Tip!
<?php
// No direct access to this file
defined('_JEXEC') or die('Restricted access');
Just a side note for completion, you could call another function aside from display() by using an URL like
this one:
http://localhost/index.php?option=com_helloworld&task=insert
10
<?php
// No direct access to this file
defined('_JEXEC') or die('Restricted access');
?>
<h1><?php echo $this->msg; ?></h1>
This would try to call a function insert() of our controller (which we would actually have to
implement in HelloWorldController ).
This template file will be included by the JView class. Therefore, here, $this refers to the
HelloWorldViewHelloWorld class.
When JController wants to display a view, it will look for certain files in the
component/com_[component_name]/views/[name of view]/ folder.
The name of the folder of the default view is the name of the component itself. In our case the
path is component/com_helloworld/views/helloworld/.
The file that will contain the code of the view is called view.[view_mode].php. The default view
mode, and probably the only view a component might need is the html mode. So this give us our
file name which is view.html.php.
With your favorite file manager and editor, create a file site/views/helloworld/view.html.php able
to display the default view and containing
site/views/helloworld/view.html.php
http://localhost/joomla/index.php?option=com_helloworld&view=helloworld
if we change &view=helloworld to something else, e.g. &view=fluffy we would have to create a
folder:
<?php
// No direct access to this file
defined('_JEXEC') or die('Restricted access');
component/com_helloworld/views/fluffy/
/**
* HTML View class for the HelloWorld Component
*/
class HelloWorldViewHelloWorld extends JView
{
// Overwriting JView display method
function display($tpl = null)
{
// Assign data to the view
$this->msg = 'Hello World';
The classname of the file view.html.php of the fluffy folder would be HelloWorldViewFluffy.
Afterwards you can customize the contents of default.php of the fluffy subfolder for custom
output and see the output by calling:
http://localhost/joomla/index.php?option=com_helloworld&view=fluffy
The display method of the JView class is called with the display task of the JController class. In
our case, this method will display data using the tmpl/default.php file. With your favorite file
manager and editor, create a file site/views/helloworld/tmpl/default.php able to display the
default view and containing
site/views/helloworld/tmpl/default.php
11
helloworld.xml
site/index.html
site/helloworld.php
site/controller.php
site/views/index.html
site/views/helloworld/index.html
site/views/helloworld/view.html.php
site/views/helloworld/tmpl/index.html
12
site/views/helloworld/tmpl/default.php
admin/index.html
admin/helloworld.php
admin/sql/index.html
admin/sql/updates/index.html
admin/sql/updates/mysql/index.html
admin/sql/updates/mysql/0.0.1.sql
folder
to copy FROM in the package to install therefore
files copied
in this section are copied from /admin/ in the
package -->
<files folder="admin">
<!-- Admin Main File Copy Section -->
<filename>index.html</filename>
<filename>helloworld.php</filename>
<!-- SQL files section -->
<folder>sql</folder>
</files>
</administration>
Create a compressed file of this directory or directly download the archive and install it using the
extension manager of Joomla. You can test this basic component by putting
index.php?option=com_helloworld in your browser address.
helloworld.xml
</extension>
Result: You will see by default the message contained in the variable $this->msg in the
view.html.php file.
<name>Hello World!</name>
<!-- The following elements are optional and free of formatting
constraints -->
<creationDate>November 2009</creationDate>
<author>John Doe</author>
<authorEmail>[email protected]</authorEmail>
<authorUrl>http://www.example.org</authorUrl>
<copyright>Copyright Info</copyright>
<license>License Info</license>
<!-- The version string is recorded in the components table -->
<version>0.0.2</version>
<!-- The description is optional and defaults to the name -->
<description>Description of the Hello World component
...</description>
Contents
[Expand]
Introduction
<administration>
<!-- Administration Menu Section -->
<menu>Hello World!</menu>
<!-- Administration Main File Copy Section -->
14
13
1 Introduction
2 Abstract
3 Adding a menu item type
4 Packaging the component
5 Navigate
6 Contributors
Abstract
Generally speaking, this article describes how to get a link on your joomla page to open a
specific page of your component. This gets simply done by adding an xml file to your specific
page into your view folder.
E.g.
site/views/helloworld/tmpl/
Contains your view page default.php that we want to open.
A file default.xml is placed next to this file with some xml. This makes joomla able to recognize
the view file default.php as a menu item.
<administration>
<!-- Administration Menu Section -->
<menu>Hello World!</menu>
<!-- Administration Main File Copy Section -->
<!-- Note the folder attribute: This attribute describes the
site/views/helloworld/tmpl/default.xml
<?xml version="1.0" encoding="utf-8"?>
<metadata>
<layout title="COM_HELLOWORLD_HELLOWORLD_VIEW_DEFAULT_TITLE">
<message>
folder
to copy FROM in the package to install therefore
files copied
<![CDATA[COM_HELLOWORLD_HELLOWORLD_VIEW_DEFAULT_DESC]]>
</message>
</layout>
</metadata>
For the moment the strings won't be translated in the administrator interface. We will see in a
later article how translation is performed.
Also modify your helloworld.xml file to indicate a new version:
</extension>
helloworld.xml
15
16
Contents
helloworld.xml
site/index.html
site/helloworld.php
site/controller.php
site/views/index.html
site/views/helloworld/index.html
site/views/helloworld/view.html.php
site/views/helloworld/tmpl/index.html
site/views/helloworld/tmpl/default.xml
site/views/helloworld/tmpl/default.php
admin/index.html
admin/helloworld.php
admin/sql/index.html
admin/sql/updates/index.html
admin/sql/updates/mysql/index.html
admin/sql/updates/mysql/0.0.1.sql
1 Introduction
2 Adding a model
3 Packaging the component
4 Navigate
5 Contributors
[Expand]
Introduction
This tutorial is part of the Developing a Model-View-Controller (MVC) Component for
Joomla!2.5 tutorial. You are encouraged to read the previous parts of the tutorial before reading
this.
Adding a model
In the Joomla framework, models are responsible for managing the data. The first function that
has to be written for a model is a get function. It returns data to the caller. In our case, the caller
will be the HelloWorldViewHelloWorld view. By default, the model named
HelloWorldModelHelloWorld residing in site/models/helloworld.php is the main model
associated to this view.
So let's have a quick look at the naming conventions with an example, since the naming
convention are the actual magic, that make everything work:
The class HelloWorldViewHelloWorld resides in site/views/helloworld/view.html.php and will
make use of the class HelloWorldModelHelloWorld in the file site/models/helloworld.php
So let's just assume we want to use an imaginary view fluffy, you would have to have:
Breaking any of these bold conventions will lead to errors or a blank page.
17
18
<?php
// No direct access to this file
defined('_JEXEC') or die('Restricted access');
'jerror');
return false;
}
// Display the view
parent::display($tpl);
}
}
Note: $this->get() is a member of JView::get which is a proxy to get* methods of the default
model where * is populated with the value of the first parameter passed to get()
Also modify your helloworld.xml file to indicate use of models and the new version:
helloworld.xml
/**
* Get the message
* @return string The message to be displayed to the user
*/
public function getMsg()
{
if (!isset($this->msg))
{
$this->msg = 'Hello World!';
}
return $this->msg;
}
The HelloWorldViewHelloWorld class asks the model for data using the get method of the JView
class:
site/views/helloworld/view.html.php
<name>Hello World!</name>
<!-- The following elements are optional and free of formatting
constraints -->
<creationDate>November 2009</creationDate>
<author>John Doe</author>
<authorEmail>[email protected]</authorEmail>
<authorUrl>http://www.example.org</authorUrl>
<copyright>Copyright Info</copyright>
<license>License Info</license>
<!-- The version string is recorded in the components table -->
<version>0.0.4</version>
<!-- The description is optional and defaults to the name -->
<description>Description of the Hello World component
...</description>
<update> <!-- Runs on update; New in 2.5 -->
<schemas>
<schemapath
type="mysql">sql/updates/mysql</schemapath>
</schemas>
</update>
<?php
// No direct access to this file
defined('_JEXEC') or die('Restricted access');
// import Joomla view library
jimport('joomla.application.component.view');
/**
* HTML View class for the HelloWorld Component
*/
19
20
admin/sql/updates/mysql/0.0.1.sql
Create a compressed file of this directory or directly download the archive and install it using the
extension manager of Joomla. You can add a menu item of this component using the menu
manager in the backend.
<administration>
<!-- Administration Menu Section -->
<menu>Hello World!</menu>
<!-- Administration Main File Copy Section -->
<!-- Note the folder attribute: This attribute describes the
folder
to copy FROM in the package to install therefore
files copied
in this section are copied from /admin/ in the
package -->
<files folder="admin">
<!-- Admin Main File Copy Section -->
<filename>index.html</filename>
<filename>helloworld.php</filename>
<!-- SQL files section -->
<folder>sql</folder>
</files>
</administration>
Contents
</extension>
[Expand]
helloworld.xml
site/index.html
site/helloworld.php
site/controller.php
site/views/index.html
site/views/helloworld/index.html
site/views/helloworld/view.html.php
site/views/helloworld/tmpl/index.html
site/views/helloworld/tmpl/default.xml
site/views/helloworld/tmpl/default.php
site/models/index.html
site/models/helloworld.php
admin/index.html
admin/helloworld.php
admin/sql/index.html
admin/sql/updates/index.html
admin/sql/updates/mysql/index.html
Introduction
This tutorial is part of the Developing a Model-View-Controller (MVC) Component for
Joomla!2.5 tutorial. You are encouraged to read the previous parts of the tutorial before reading
this.
21
1 Introduction
2 Adding a variable request in the menu type
3 Packaging the component
4 Navigate
5 Contributors
<message>COM_HELLOWORLD_HELLOWORLD_VIEW_DEFAULT_DESC</message>
</layout>
<fields name="request">
<fieldset name="request">
<field
name="id"
type="list"
label="COM_HELLOWORLD_HELLOWORLD_FIELD_GREETING_LABEL"
description="COM_HELLOWORLD_HELLOWORLD_FIELD_GREETING_DESC"
default="1"
>
<option value="1">Hello World!</option>
<option value="2">Good bye World!</option>
</field>
</fieldset>
</fields>
</metadata>
switch ($id)
{
case 2:
$this->msg = 'Good bye World!';
break;
default:
case 1:
$this->msg = 'Hello World!';
break;
}
}
return $this->msg;
}
}
helloworld.xml
site/models/helloworld.php
<?php
// No direct access to this file
defined('_JEXEC') or die('Restricted access');
<name>Hello World!</name>
<!-- The following elements are optional and free of formatting
constraints -->
<creationDate>November 2009</creationDate>
<author>John Doe</author>
<authorEmail>[email protected]</authorEmail>
<authorUrl>http://www.example.org</authorUrl>
<copyright>Copyright Info</copyright>
<license>License Info</license>
<!-- The version string is recorded in the components table -->
<version>0.0.5</version>
<!-- The description is optional and defaults to the name -->
<description>Description of the Hello World component
...</description>
/**
* Get the message
23
24
</schemas>
</update>
<!-- Site Main File Copy Section -->
<!-- Note the folder attribute: This attribute describes the folder
to copy FROM in the package to install therefore files copied
in this section are copied from /site/ in the package -->
<files folder="site">
<filename>index.html</filename>
<filename>helloworld.php</filename>
<filename>controller.php</filename>
<folder>views</folder>
<folder>models</folder>
</files>
<administration>
<!-- Administration Menu Section -->
<menu>Hello World!</menu>
<!-- Administration Main File Copy Section -->
<!-- Note the folder attribute: This attribute describes the
site/views/helloworld/tmpl/default.php
site/models/index.html
site/models/helloworld.php
admin/index.html
admin/helloworld.php
admin/sql/index.html
admin/sql/updates/index.html
admin/sql/updates/mysql/index.html
admin/sql/updates/mysql/0.0.1.sql
Create a compressed file of this directory or directly download the archive and install it using the
extension manager of Joomla. You can add a menu item of this component using the menu
manager in the backend.
folder
package -->
<files folder="admin">
<!-- Admin Main File Copy Section -->
<filename>index.html</filename>
<filename>helloworld.php</filename>
<!-- SQL files section -->
<folder>sql</folder>
</files>
</administration>
Contents
</extension>
1 Introduction
2 Using the database
3 Adding a new field type
4 Display the chosen message
5 Packaging the component
6 Navigate
7 Contributors
[Expand]
helloworld.xml
site/index.html
site/helloworld.php
site/controller.php
site/views/index.html
site/views/helloworld/index.html
site/views/helloworld/view.html.php
site/views/helloworld/tmpl/index.html
site/views/helloworld/tmpl/default.xml
Introduction
This tutorial is part of the Developing a Model-View-Controller (MVC) Component for
Joomla!2.5 tutorial. You are encouraged to read the previous parts of the tutorial before reading
this.
26
25
<authorEmail>[email protected]</authorEmail>
<authorUrl>http://www.example.org</authorUrl>
<copyright>Copyright Info</copyright>
<license>License Info</license>
<!-- The version string is recorded in the components table -->
<version>0.0.6</version>
<!-- The description is optional and defaults to the name -->
<description>Description of the Hello World component
...</description>
<install> <!-- Runs on install -->
<sql>
<file driver="mysql"
charset="utf8">sql/install.mysql.utf8.sql</file>
</sql>
</install>
<uninstall> <!-- Runs on uninstall -->
<sql>
<file driver="mysql"
charset="utf8">sql/uninstall.mysql.utf8.sql</file>
</sql>
</uninstall>
<update> <!-- Runs on update; New in 2.5 -->
<schemas>
<schemapath
type="mysql">sql/updates/mysql</schemapath>
</schemas>
</update>
The file install.mysql.utf8.sql will be executed when you install this component. The file
0.0.6.sql is executed when you do an update.
Important Note: When the component is installed, the files in the SQL updates folder (for
example, admin/sql/updates/mysql) are read and the name of the last file alphabetically is used to
populate the component's version number in the #__schemas table. This value must be in this
table in order for the automatic update to execute the update SQL files for future versions. For
this reason, it is good practice to create a SQL update file for each version (even if it is empty or
just has a comment). This way the #__schemas version will always match the component
version.
Important Note: When saving the SQL files in utf8, be sure to save them as utf8 NO BOM or
the query will fail with MySQL error #1064.
<administration>
<!-- Administration Menu Section -->
<menu>Hello World!</menu>
<!-- Administration Main File Copy Section -->
<!-- Note the folder attribute: This attribute describes the
This is the install file. It will be executed if you put an appropriate order in the helloworld.xml
file
helloworld.xml
folder
files copied
<name>Hello World!</name>
<!-- The following elements are optional and free of formatting
constraints -->
<creationDate>November 2009</creationDate>
<author>John Doe</author>
27
28
It introduces a new field type and tells Joomla to look for the field definition in the
/administrator/components/com_helloworld/models/fields folder.
With your favorite file manager and editor put a file admin/models/fields/helloworld.php file
containing:
</files>
</administration>
</extension>
admin/models/fields/helloworld.php
<?php
// No direct access to this file
defined('_JEXEC') or die;
With your favorite file manager and editor put a file admin/sql/uninstall.mysql.utf8.sql
containing:
admin/sql/uninstall.mysql.utf8.sql
/**
* HelloWorld Form Field class for the HelloWorld component
*/
class JFormFieldHelloWorld extends JFormFieldList
{
/**
* The field type.
*
* @var
string
*/
protected $type = 'HelloWorld';
/**
* Method to get a list of options for a list input.
*
* @return
array
An array of JHtml options.
*/
protected function getOptions()
{
$db = JFactory::getDBO();
$query = $db->getQuery(true);
$query->select('id,greeting');
$query->from('#__helloworld');
$db->setQuery((string)$query);
$messages = $db->loadObjectList();
$options = array();
if ($messages)
{
foreach($messages as $message)
{
$options[] = JHtml::_('select.option',
$message->id, $message->greeting);
}
}
$options = array_merge(parent::getOptions(), $options);
return $options;
}
}
29
30
$this->messages = array();
The new field type displays a drop-down list of messages to choose from. You can see the result
of this change in the menu manager section for the helloworld item.
}
if (!isset($this->messages[$id]))
{
//request the selected id
$jinput = JFactory::getApplication()->input;
$id = $jinput->get('id', 1, 'INT' );
site/models/helloworld.php
<?php
// No direct access to this file
defined('_JEXEC') or die('Restricted access');
}
return $this->messages[$id];
}
/**
* HelloWorld Model
*/
class HelloWorldModelHelloWorld extends JModelItem
{
/**
* @var array messages
*/
protected $messages;
The model now asks the TableHelloWorld to get the message. This table class has to be defined
in admin/tables/helloworld.php file
/**
* Returns a reference to the a Table object, always creating it.
*
* @param
type
The table type to instantiate
* @param
string A prefix for the table class name. Optional.
* @param
array
Configuration array for model. Optional.
* @return
JTable A database object
* @since
2.5
*/
public function getTable($type = 'HelloWorld', $prefix =
'HelloWorldTable', $config = array())
{
return JTable::getInstance($type, $prefix, $config);
}
/**
* Get the message
* @param int
The corresponding id of the message to be retrieved
* @return string The message to be displayed to the user
*/
public function getMsg($id = 1)
{
if (!is_array($this->messages))
{
admin/tables/helloworld.php
<?php
// No direct access
defined('_JEXEC') or die('Restricted access');
/**
* Hello Table class
*/
class HelloWorldTableHelloWorld extends JTable
{
/**
* Constructor
*
* @param object Database connector object
*/
function __construct(&$db)
{
parent::__construct('#__helloworld', 'id', $db);
}
}
You shouldn't see any differences, but if you access the database you should see a table named
jos_helloworld with two columns: id and greeting. And two entries: Hello World! and Good bye
World
31
32
Contents
helloworld.xml
site/index.html
site/helloworld.php
site/controller.php
site/views/index.html
site/views/helloworld/index.html
site/views/helloworld/view.html.php
site/views/helloworld/tmpl/index.html
site/views/helloworld/tmpl/default.xml
site/views/helloworld/tmpl/default.php
site/models/index.html
site/models/helloworld.php
admin/index.html
admin/helloworld.php
admin/sql/index.html
admin/sql/install.mysql.utf8.sql
admin/sql/uninstall.mysql.utf8.sql
admin/sql/updates/index.html
admin/sql/updates/mysql/index.html
admin/sql/updates/mysql/0.0.1.sql
admin/sql/updates/mysql/0.0.6.sql
admin/models/index.html
admin/models/fields/index.html
admin/models/fields/helloworld.php
admin/tables/index.html
admin/tables/helloworld.php
1 Introduction
2 Basic backend
3 Create the general controller
4 Create the view
5 Create the model
6 Packaging the component
7 Navigate
8 Contributors
[Expand]
Introduction
This tutorial is part of the Developing a Model-View-Controller (MVC) Component for
Joomla!2.5 tutorial. You are encouraged to read the previous parts of the tutorial before reading
this.
And check the "discussion" tab for some clarifications.
Basic backend
Create a compressed file of this directory or directly download the archive and install it using the
extension manager of Joomla. You can add a menu item of this component using the menu
manager in the backend.
Note: site/models/helloworld.php is not up-to-date as mentioned on this page. You need to copy
the code yourself.
<?php
// No direct access to this file
defined('_JEXEC') or die('Restricted access');
34
33
<?php
// No direct access to this file
defined('_JEXEC') or die('Restricted access');
/**
* HelloWorlds View
*/
class HelloWorldViewHelloWorlds extends JView
{
/**
* HelloWorlds view display method
* @return void
*/
function display($tpl = null)
{
// Get data from the model
$items = $this->get('Items');
$pagination = $this->get('Pagination');
The entry point now gets an instance of a HelloWorld prefixed controller. Let's create a basic
controller for the administrator part:
admin/controller.php
<?php
// No direct access to this file
defined('_JEXEC') or die('Restricted access');
// import Joomla controller library
jimport('joomla.application.component.controller');
/**
* General Controller of HelloWorld component
*/
class HelloWorldController extends JController
{
/**
* display task
*
* @return void
*/
function display($cachable = false, $urlparams = false)
{
// set default view if not set
$input = JFactory::getApplication()->input;
$input->set('view', $input->getCmd('view', 'HelloWorlds'));
In Joomla, views display data using layout. With your favorite file manager and editor, put a file
admin/views/helloworlds/tmpl/default.php containing
admin/views/helloworlds/tmpl/default.php
}
}
<?php
// No direct access to this file
defined('_JEXEC') or die('Restricted Access');
35
36
</table>
</td>
<td>
</form>
This layout calls several sub-layout (head, foot and body). Each sub-layout corresponds to a file
prefixed by the name of the main layout (default), and an underscore.
Put a file admin/views/helloworlds/tmpl/default_head.php containing
</td>
</tr>
<?php endforeach; ?>
JHtml::_ is a helper function able to display several HTML output. In this case, it will display a
checkbox for the item.
admin/views/helloworlds/tmpl/default_head.php
<?php
// No direct access to this file
defined('_JEXEC') or die('Restricted Access');
?>
<tr>
<th width="5">
<?php echo JText::_('COM_HELLOWORLD_HELLOWORLD_HEADING_ID');
?>
</th>
<th width="20">
<input type="checkbox" name="toggle" value=""
onclick="checkAll(<?php echo count($this->items); ?>);" />
</th>
<th>
<?php echo
JText::_('COM_HELLOWORLD_HELLOWORLD_HEADING_GREETING'); ?>
</th>
</tr>
admin/views/helloworlds/tmpl/default_foot.php
<?php
// No direct access to this file
defined('_JEXEC') or die('Restricted Access');
?>
<tr>
<td colspan="3"><?php echo $this->pagination->getListFooter();
?></td>
</tr>
COM_HELLOWORLD_HELLOWORLD_HEADING_ID and
COM_HELLOWORLD_HELLOWORLD_HEADING_GREETING are placeholders which will
later be replaced with language-specific text. The JText::_ method translates a string into the
current language.
checkAll is a javascript function defined in the Joomla core able to check all items.
The getItems and getPagination methods are defined in JModelList class. They don't need to be
defined in the HelloWorldModelHelloWorlds class.
admin/views/helloworlds/tmpl/default_body.php
<?php
// No direct access to this file
defined('_JEXEC') or die('Restricted Access');
?>
<?php foreach($this->items as $i => $item): ?>
<tr class="row<?php echo $i % 2; ?>">
<td>
<?php echo $item->id; ?>
</td>
<td>
<?php echo JHtml::_('grid.id', $i, $item->id); ?>
admin/models/helloworlds.php
<?php
// No direct access to this file
defined('_JEXEC') or die('Restricted access');
// import the Joomla modellist library
jimport('joomla.application.component.modellist');
/**
* HelloWorldList Model
*/
37
38
Create a compressed file of this directory or directly download the archive and install it using the
extension manager of Joomla. You can add a menu item of this component using the menu
manager in the backend.
The _populateState method is, by default, automatically called when a state is read by the
getState method.
helloworld.xml
helloworld.xml
site/index.html
site/helloworld.php
site/controller.php
site/views/index.html
site/views/helloworld/index.html
site/views/helloworld/view.html.php
site/views/helloworld/tmpl/index.html
site/views/helloworld/tmpl/default.xml
site/views/helloworld/tmpl/default.php
site/models/index.html
site/models/helloworld.php
admin/index.html
admin/helloworld.php
admin/controller.php
admin/sql/index.html
admin/sql/install.mysql.utf8.sql
admin/sql/uninstall.mysql.utf8.sql
admin/sql/updates/index.html
admin/sql/updates/mysql/index.html
admin/sql/updates/mysql/0.0.1.sql
admin/sql/updates/mysql/0.0.6.sql
39
admin/models/index.html
admin/models/fields/index.html
admin/models/fields/helloworld.php
admin/models/helloworlds.php
admin/views/index.html
admin/views/helloworlds/index.html
admin/views/helloworlds/view.html.php
admin/views/helloworlds/tmpl/index.html
admin/views/helloworlds/tmpl/default.php
admin/views/helloworlds/tmpl/default_head.php
admin/views/helloworlds/tmpl/default_body.php
admin/views/helloworlds/tmpl/default_foot.php
admin/tables/index.html
admin/tables/helloworld.php
40
<files folder="site">
<filename>index.html</filename>
<filename>helloworld.php</filename>
<filename>controller.php</filename>
<folder>views</folder>
<folder>models</folder>
</files>
Introduction
This tutorial is part of the Developing a Model-View-Controller (MVC) Component for
Joomla!2.5 tutorial. You are encouraged to read the previous parts of the tutorial before reading
this.
<administration>
<menu>Hello World!</menu>
<files folder="admin">
<filename>index.html</filename>
<filename>helloworld.php</filename>
<filename>controller.php</filename>
<folder>sql</folder>
<folder>tables</folder>
<folder>models</folder>
<!-- views files section -->
<folder>views</folder>
</files>
</administration>
</extension>
Now you can see in your component hello-world an array with two colums, two rows and
checkboxes. You can click the checkboxes in order to select the different options you want.
With your favorite file manager and editor, put a file site/language/en-GB/enGB.com_helloworld.ini. This file will contain translation for the public part. For the moment, this
file is empty
site/language/en-GB/en-GB.com_helloworld.ini
Contents
1 Introduction
2 Adding language translation in the public site
3 Adding language translation when managing the component
4 Adding language translation when managing the menus in the backend
5 Language File Location Options
6 Adding translation when installing the component
7 Packaging the component
8 Navigate
9 Contributors
[Expand]
41
42
[...]
</files>
With your favorite file manager and editor, put a file admin/language/en-GB/enGB.com_helloworld.sys.ini. This file will contain translation for the backend part.
admin/language/en-GB/en-GB.com_helloworld.sys.ini
or simply in ROOT
COM_HELLOWORLD="Hello World!"
COM_HELLOWORLD_DESCRIPTION="This is the Hello World description"
COM_HELLOWORLD_HELLOWORLD_VIEW_DEFAULT_TITLE="Hello World"
COM_HELLOWORLD_HELLOWORLD_VIEW_DEFAULT_DESC="This view displays a selected
message"
COM_HELLOWORLD_MENU="Hello World!"
<languages>
<language tag="en-GB">en-GB.whatever.ini</language>
<language tag="en-GB">en-GB.whatever.sys.ini</language>
</languages>
Language file used by the install script during install of a component(the first install not
upgrade) obeys specific rules described at
http://docs.joomla.org/Specification_of_language_files. During the first install, only the
language file included in the component folder
(/administrator/components/com_helloworld/language) is used when present. If this file is only
provided in the CORE language folder (/administrator/language), no translation occurs. This also
applies to KEYs used in the manifest file.
When upgrading or uninstalling the extension (not installing), it is the sys.ini file present in the
extension root language folder which will display the result of the install from the description
key/value. Thereafter, if present, the sys.ini as well as the ini installed in CORE language folder
will have priority over the files present in the root language folder of the extension.
Note: One advantage of installing the files in the extension "language" folder is that these are
not touched when updating a language pack. The other advantage is that this folder can include
multiple languages (en-GB always, fr-FR, it-IT, etc.) not requiring the user to install the
corresponding language pack. This is handy as they are available if, later on, a user installs the
corresponding pack.
With your favorite file manager and editor, put a file EXTENSIONROOT/language/en-GB/enGB.myextension.sys.ini. This file will contain translation for the install.
<files>
<[...]
<folder>language</folder> // This folder HAS to include the right
subfolders, i.e. language/en-GB/ ... language/fr-FR/
<filename>whatever</filename>
language/en-GB/en-GB.myextension.sys.ini
43
44
COM_HELLOWORLD="Hello World!"
COM_HELLOWORLD_DESCRIPTION="This is the Hello World description"
admin/tables/index.html
admin/tables/helloworld.php
admin/language/en-GB/en-GB.com_helloworld.ini
admin/language/en-GB/en-GB.com_helloworld.sys.ini
language/en-GB/en-GB.ini
helloworld.xml
site/index.html
site/helloworld.php
site/controller.php
site/views/index.html
site/views/helloworld/index.html
site/views/helloworld/view.html.php
site/views/helloworld/tmpl/index.html
site/views/helloworld/tmpl/default.xml
site/views/helloworld/tmpl/default.php
site/models/index.html
site/models/helloworld.php
site/language/index.html
site/language/en-GB/index.html
site/language/en-GB/en-GB.com_helloworld.ini
admin/index.html
admin/helloworld.php
admin/controller.php
admin/sql/index.html
admin/sql/install.mysql.utf8.sql
admin/sql/uninstall.mysql.utf8.sql
admin/sql/updates/index.html
admin/sql/updates/mysql/index.html
admin/sql/updates/mysql/0.0.1.sql
admin/sql/updates/mysql/0.0.6.sql
admin/models/index.html
admin/models/fields/index.html
admin/models/fields/helloworld.php
admin/models/helloworlds.php
admin/views/index.html
admin/views/helloworlds/index.html
admin/views/helloworlds/view.html.php
admin/views/helloworlds/tmpl/index.html
admin/views/helloworlds/tmpl/default.php
admin/views/helloworlds/tmpl/default_head.php
admin/views/helloworlds/tmpl/default_body.php
admin/views/helloworlds/tmpl/default_foot.php
helloworld.xml
<?xml version="1.0" encoding="utf-8"?>
<extension type="component" version="2.5.0" method="upgrade">
<name>COM_HELLOWORLD</name>
<!-- The following elements are optional and free of formatting
constraints -->
<creationDate>November 2009</creationDate>
<author>John Doe</author>
<authorEmail>[email protected]</authorEmail>
<authorUrl>http://www.example.org</authorUrl>
<copyright>Copyright Info</copyright>
<license>License Info</license>
<!-- The version string is recorded in the components table -->
<version>0.0.8</version>
<!-- The description is optional and defaults to the name -->
<description>COM_HELLOWORLD_DESCRIPTION</description>
<install> <!-- Runs on install -->
<sql>
<file driver="mysql"
charset="utf8">sql/install.mysql.utf8.sql</file>
</sql>
</install>
<uninstall> <!-- Runs on uninstall -->
<sql>
<file driver="mysql"
charset="utf8">sql/uninstall.mysql.utf8.sql</file>
</sql>
</uninstall>
<update> <!-- Runs on update; New in 2.5 -->
<schemas>
<schemapath
type="mysql">sql/updates/mysql</schemapath>
</schemas>
</update>
<!-- Site Main File Copy Section -->
<!-- Note the folder attribute: This attribute describes the folder
to copy FROM in the package to install therefore files copied
in this section are copied from /site/ in the package -->
<files folder="site">
<filename>index.html</filename>
45
46
<filename>helloworld.php</filename>
<filename>controller.php</filename>
<folder>views</folder>
<folder>models</folder>
<folder>language</folder>
</files>
Contents
<administration>
<!-- Administration Menu Section -->
<menu>COM_HELLOWORLD_MENU</menu>
<!-- Administration Main File Copy Section -->
<!-- Note the folder attribute: This attribute describes the
folder
to copy FROM in the package to install therefore
files copied
in this section are copied from /admin/ in the
package -->
<files folder="admin">
<!-- Admin Main File Copy Section -->
<filename>index.html</filename>
<filename>helloworld.php</filename>
<filename>controller.php</filename>
<!-- SQL files section -->
<folder>sql</folder>
<!-- tables files section -->
<folder>tables</folder>
<!-- models files section -->
<folder>models</folder>
<!-- views files section -->
<folder>views</folder>
</files>
<languages folder="admin">
<language tag="en-GB">language/en-GB/enGB.com_helloworld.ini</language>
<language tag="en-GB">language/en-GB/enGB.com_helloworld.sys.ini</language>
</languages>
</administration>
[Expand]
Introduction
This tutorial is part of the Developing a Model-View-Controller (MVC) Component for
Joomla!2.5 tutorial. You are encouraged to read the previous parts of the tutorial before reading
this.
Adding a toolbar
In Joomla, the administrator interacts generally with components through the use of a toolbar. In
the file admin/views/helloworlds/view.html.php put this content. It will create a basic toolbar and
a title for the component.
</extension>
1 Introduction
2 Adding a toolbar
3 Adding specific controllers
4 Adding an editing view
5 Adding a model and modifying the existing one
6 Packaging the component
7 Navigate
8 Contributors
administrator/language for the admin part (look at the xml languages tag)
components/com_helloworld/language for the site part (there are no xml languages tag in
the site part of the xml description file, but the language folder is included)
The corrected zip file, download and delete the .png extension before use: [1]
The args used in ex. JToolBarHelper::addNew is used to set a controller instance which will be
used after button is clicked.
admin/views/helloworlds/view.html.php
<?php
// No direct access to this file
defined('_JEXEC') or die('Restricted access');
48
47
* HelloWorlds View
*/
class HelloWorldViewHelloWorlds extends JView
{
/**
* HelloWorlds view display method
* @param
string $tpl The name of the template file to parse;
automatically searches through the template paths.
*
* @return mixed A string if successful, otherwise a JError object.
*/
function display($tpl = null)
{
// Get data from the model
$items = $this->get('Items');
$pagination = $this->get('Pagination');
// Check for errors.
if (count($errors = $this->get('Errors')))
{
JError::raiseError(500, implode('<br />', $errors));
return false;
}
// Assign data to the view
$this->items = $items;
$this->pagination = $pagination;
<?php
// No direct access to this file
defined('_JEXEC') or die('Restricted Access');
// load tooltip behavior
JHtml::_('behavior.tooltip');
?>
<form action="<?php echo JRoute::_('index.php?option=com_helloworld'); ?>"
method="post" name="adminForm" id="adminForm">
<table class="adminlist">
<thead><?php echo $this->loadTemplate('head');?></thead>
<tfoot><?php echo $this->loadTemplate('foot');?></tfoot>
<tbody><?php echo $this->loadTemplate('body');?></tbody>
</table>
<div>
<input type="hidden" name="task" value="" />
<input type="hidden" name="boxchecked" value="0" />
<?php echo JHtml::_('form.token'); ?>
</div>
</form>
helloworlds.delete
helloworld.edit
helloworld.add
/**
* Setting the toolbar
*/
protected function addToolBar()
{
admin/controllers/helloworlds.php
<?php
// No direct access to this file
defined('_JEXEC') or die('Restricted access');
JToolBarHelper::title(JText::_('COM_HELLOWORLD_MANAGER_HELLOWORLDS'));
JToolBarHelper::deleteList('', 'helloworlds.delete');
JToolBarHelper::editList('helloworld.edit');
JToolBarHelper::addNew('helloworld.add');
}
}
You can find other classic backend actions in the administrator/includes/toolbar.php file of your
Joomla installation.
Since the view can perform some actions, we have to add some input data. With your favorite
file manager and editor, put in the file admin/views/helloworlds/tmpl/default.php
admin/views/helloworlds/tmpl/default.php
/**
* HelloWorlds Controller
*/
class HelloWorldControllerHelloWorlds extends JControllerAdmin
{
/**
* Proxy for getModel.
* @since
2.5
*/
49
50
admin/controllers/helloworld.php
<?php
// No direct access to this file
defined('_JEXEC') or die('Restricted access');
/**
* Setting the toolbar
*/
protected function addToolBar()
{
$input = JFactory::getApplication()->input;
$input->set('hidemainmenu', true);
$isNew = ($this->item->id == 0);
JToolBarHelper::title($isNew ?
JText::_('COM_HELLOWORLD_MANAGER_HELLOWORLD_NEW')
:
JText::_('COM_HELLOWORLD_MANAGER_HELLOWORLD_EDIT'));
JToolBarHelper::save('helloworld.save');
JToolBarHelper::cancel('helloworld.cancel', $isNew ?
'JTOOLBAR_CANCEL'
:
'JTOOLBAR_CLOSE');
}
}
/**
* HelloWorld Controller
*/
class HelloWorldControllerHelloWorld extends JControllerForm
{
}
/**
* HelloWorld View
*/
class HelloWorldViewHelloWorld extends JView
{
/**
* display method of Hello view
* @return void
*/
public function display($tpl = null)
{
// get the Data
$form = $this->get('Form');
$item = $this->get('Item');
admin/views/helloworld/tmpl/edit.php
<?php
// No direct access
defined('_JEXEC') or die('Restricted access');
JHtml::_('behavior.tooltip');
?>
<form action="<?php echo
JRoute::_('index.php?option=com_helloworld&layout=edit&id='.(int) $this>item->id); ?>"
method="post" name="adminForm" id="adminForm">
<fieldset class="adminform">
<legend><?php echo JText::_(
'COM_HELLOWORLD_HELLOWORLD_DETAILS' ); ?></legend>
51
52
<ul class="adminformlist">
<?php foreach($this->form->getFieldset() as $field): ?>
<li><?php echo $field->label;echo $field>input;?></li>
<?php endforeach; ?>
</ul>
</fieldset>
<div>
<input type="hidden" name="task" value="helloworld.edit" />
<?php echo JHtml::_('form.token'); ?>
</div>
</form>
* @since
2.5
*/
public function getForm($data = array(), $loadData = true)
{
// Get the form.
$form = $this->loadForm('com_helloworld.helloworld',
'helloworld',
array('control' => 'jform',
'load_data' => $loadData));
if (empty($form))
{
return false;
}
return $form;
}
/**
* Method to get the data that should be injected in the form.
*
* @return
mixed
The data for the form.
* @since
2.5
*/
protected function loadFormData()
{
// Check the session for previously entered form data.
$data = JFactory::getApplication()>getUserState('com_helloworld.edit.helloworld.data', array());
if (empty($data))
{
$data = $this->getItem();
}
return $data;
}
}
This model inherits from the JModelAdmin class and uses its loadForm method. This method
searches for forms in the forms folder. With your favorite file manager and editor, put a file
admin/models/forms/helloworld.xml containing:
admin/models/forms/helloworld.xml
<?xml version="1.0" encoding="utf-8"?>
<form>
<fieldset>
<field
name="id"
type="hidden"
/>
<field
name="greeting"
type="text"
label="COM_HELLOWORLD_HELLOWORLD_GREETING_LABEL"
description="COM_HELLOWORLD_HELLOWORLD_GREETING_DESC"
size="40"
class="inputbox"
default=""
53
54
/>
</fieldset>
</form>
helloworld.xml
site/index.html
site/helloworld.php
site/controller.php
site/views/index.html
site/views/helloworld/index.html
site/views/helloworld/view.html.php
site/views/helloworld/tmpl/index.html
site/views/helloworld/tmpl/default.xml
site/views/helloworld/tmpl/default.php
site/models/index.html
site/models/helloworld.php
site/language/index.html
site/language/en-GB/index.html
site/language/en-GB/en-GB.com_helloworld.ini
admin/index.html
admin/helloworld.php
admin/controller.php
admin/sql/index.html
admin/sql/install.mysql.utf8.sql
admin/sql/uninstall.mysql.utf8.sql
admin/sql/updates/index.html
admin/sql/updates/mysql/index.html
admin/sql/updates/mysql/0.0.1.sql
admin/sql/updates/mysql/0.0.6.sql
admin/models/index.html
admin/models/fields/index.html
admin/models/fields/helloworld.php
admin/models/forms/index.html
admin/models/forms/helloworld.xml
admin/models/helloworld.php
admin/models/helloworlds.php
admin/views/index.html
admin/views/helloworlds/index.html
admin/views/helloworlds/view.html.php
admin/views/helloworlds/tmpl/index.html
admin/views/helloworlds/tmpl/default.php
admin/views/helloworlds/tmpl/default_head.php
Create a compressed file of this directory or directly download the archive, modify the code in
/admin/models/helloworld.php and install it using the extension manager of Joomla. You can add
a menu item of this component using the menu manager in the backend.
helloworld.xml
<?xml version="1.0" encoding="utf-8"?>
<extension type="component" version="2.5.0" method="upgrade">
<name>Hello World!</name>
<!-- The following elements are optional and free of formatting
constraints -->
<creationDate>November 2009</creationDate>
<author>John Doe</author>
<authorEmail>[email protected]</authorEmail>
<authorUrl>http://www.example.org</authorUrl>
<copyright>Copyright Info</copyright>
<license>License Info</license>
<!-- The version string is recorded in the components table -->
<version>0.0.9</version>
<!-- The description is optional and defaults to the name -->
<description>COM_HELLOWORLD_DESCRIPTION</description>
<install> <!-- Runs on install -->
<sql>
<file driver="mysql"
charset="utf8">sql/install.mysql.utf8.sql</file>
</sql>
</install>
<uninstall> <!-- Runs on uninstall -->
<sql>
<file driver="mysql"
charset="utf8">sql/uninstall.mysql.utf8.sql</file>
</sql>
</uninstall>
<update> <!-- Runs on update; New in 2.5 -->
55
admin/views/helloworlds/tmpl/default_body.php
admin/views/helloworlds/tmpl/default_foot.php
admin/views/helloworld/index.html
admin/views/helloworld/view.html.php
admin/views/helloworld/tmpl/index.html
admin/views/helloworld/tmpl/edit.php
admin/tables/index.html
admin/tables/helloworld.php
admin/language/en-GB/en-GB.com_helloworld.ini
admin/language/en-GB/en-GB.com_helloworld.sys.ini
admin/controllers/index.html
admin/controllers/helloworld.php
admin/controllers/helloworlds.php
language/en-GB/en-GB.ini
56
<schemas>
<schemapath
type="mysql">sql/updates/mysql</schemapath>
</schemas>
</update>
Contents
<administration>
<!-- Administration Menu Section -->
<menu>COM_HELLOWORLD_MENU</menu>
<!-- Administration Main File Copy Section -->
<!-- Note the folder attribute: This attribute describes the
1 Introduction
2 Adding some icons
3 Modifying the views
4 Modifying the main entry file
5 Adding some strings in the language file
6 Packaging the component
7 Navigate
8 Contributors
folder
to copy FROM in the package to install therefore
[Expand]
files copied
in this section are copied from /admin/ in the
package -->
<files folder="admin">
<!-- Admin Main File Copy Section -->
<filename>index.html</filename>
<filename>helloworld.php</filename>
<filename>controller.php</filename>
<!-- SQL files section -->
<folder>sql</folder>
<!-- tables files section -->
<folder>tables</folder>
<!-- models files section -->
<folder>models</folder>
<!-- views files section -->
<folder>views</folder>
<!-- controllers files section -->
<folder>controllers</folder>
</files>
Introduction
This tutorial is part of the Developing a Model-View-Controller (MVC) Component for
Joomla!2.5 tutorial. You are encouraged to read the previous parts of the tutorial before reading
this.
<languages folder="admin">
<language tag="en-GB">language/en-GB/enGB.com_helloworld.ini</language>
<language tag="en-GB">language/en-GB/enGB.com_helloworld.sys.ini</language>
</languages>
</administration>
</extension>
admin/views/helloworlds/view.html.php
58
57
<?php
// No direct access to this file
defined('_JEXEC') or die('Restricted access');
/**
* Method to set up the document properties
*
* @return void
*/
protected function setDocument()
{
$document = JFactory::getDocument();
$document>setTitle(JText::_('COM_HELLOWORLD_ADMINISTRATION'));
}
}
This view uses a second parameter for the JToolBarHelper::title function. It will be used to
construct the css class for the title. The _setDocument method sets the browser title.
In admin/views/helloworld/view.html.php, put these lines:
admin/views/helloworld/view.html.php
<?php
// No direct access to this file
defined('_JEXEC') or die('Restricted access');
/**
* display method of Hello view
* @return void
*/
public function display($tpl = null)
{
// get the Data
$form = $this->get('Form');
$item = $this->get('Item');
/**
* Setting the toolbar
*/
protected function addToolBar($total=null)
{
JToolBarHelper::title(JText::_('COM_HELLOWORLD_MANAGER_HELLOWORLDS').
//Reflect number of items in title!
($total?' <span style="font-size: 0.5em; verticalalign: middle;">('.$total.')</span>':'')
, 'helloworld');
JToolBarHelper::deleteListX('', 'helloworlds.delete');
JToolBarHelper::editListX('helloworld.edit');
JToolBarHelper::addNewX('helloworld.add');
}
59
60
}
/**
* Setting the toolbar
*/
protected function addToolBar()
{
$input = JFactory::getApplication()->input;
$input->set('hidemainmenu', true);
$isNew = ($this->item->id == 0);
JToolBarHelper::title($isNew ?
JText::_('COM_HELLOWORLD_MANAGER_HELLOWORLD_NEW')
:
JText::_('COM_HELLOWORLD_MANAGER_HELLOWORLD_EDIT'), 'helloworld');
JToolBarHelper::save('helloworld.save');
JToolBarHelper::cancel('helloworld.cancel', $isNew ?
'JTOOLBAR_CANCEL' : 'JTOOLBAR_CLOSE');
}
/**
* Method to set up the document properties
*
* @return void
*/
protected function setDocument()
{
$isNew = ($this->item->id < 1);
$document = JFactory::getDocument();
$document->setTitle($isNew ?
JText::_('COM_HELLOWORLD_HELLOWORLD_CREATING')
:
JText::_('COM_HELLOWORLD_HELLOWORLD_EDITING'));
}
}
This view also uses the second parameter of the JToolBarHelper::title function and set the
browser title
61
helloworld.xml
site/index.html
site/helloworld.php
site/controller.php
site/views/index.html
62
site/views/helloworld/index.html
site/views/helloworld/view.html.php
site/views/helloworld/tmpl/index.html
site/views/helloworld/tmpl/default.xml
site/views/helloworld/tmpl/default.php
site/models/index.html
site/models/helloworld.php
site/language/index.html
site/language/en-GB/index.html
site/language/en-GB/en-GB.com_helloworld.ini
admin/index.html
admin/helloworld.php
admin/controller.php
admin/sql/index.html
admin/sql/install.mysql.utf8.sql
admin/sql/uninstall.mysql.utf8.sql
admin/sql/updates/index.html
admin/sql/updates/mysql/index.html
admin/sql/updates/mysql/0.0.1.sql
admin/sql/updates/mysql/0.0.6.sql
admin/models/index.html
admin/models/fields/index.html
admin/models/fields/helloworld.php
admin/models/forms/index.html
admin/models/forms/helloworld.xml
admin/models/helloworld.php
admin/models/helloworlds.php
admin/views/index.html
admin/views/helloworlds/index.html
admin/views/helloworlds/view.html.php
admin/views/helloworlds/tmpl/index.html
admin/views/helloworlds/tmpl/default.php
admin/views/helloworlds/tmpl/default_head.php
admin/views/helloworlds/tmpl/default_body.php
admin/views/helloworlds/tmpl/default_foot.php
admin/views/helloworld/index.html
admin/views/helloworld/view.html.php
admin/views/helloworld/tmpl/index.html
admin/views/helloworld/tmpl/edit.php
admin/tables/index.html
admin/tables/helloworld.php
admin/language/en-GB/en-GB.com_helloworld.ini
admin/language/en-GB/en-GB.com_helloworld.menu.ini
admin/controllers/index.html
admin/controllers/helloworld.php
admin/controllers/helloworlds.php
Create a compressed file of this directory or directly download the archive and install it using the
extension manager of Joomla. You can add a menu item of this component using the menu
manager in the backend.
helloworld.xml
<?xml version="1.0" encoding="utf-8"?>
<extension type="component" version="2.5.0" method="upgrade">
<name>Hello World!</name>
<!-- The following elements are optional and free of formatting
constraints -->
<creationDate>November 2009</creationDate>
<author>John Doe</author>
<authorEmail>[email protected]</authorEmail>
<authorUrl>http://www.example.org</authorUrl>
<copyright>Copyright Info</copyright>
<license>License Info</license>
<!-- The version string is recorded in the components table -->
<version>0.0.10</version>
<!-- The description is optional and defaults to the name -->
<description>COM_HELLOWORLD_DESCRIPTION</description>
<install> <!-- Runs on install -->
<sql>
<file driver="mysql"
charset="utf8">sql/install.mysql.utf8.sql</file>
</sql>
</install>
<uninstall> <!-- Runs on uninstall -->
<sql>
<file driver="mysql"
charset="utf8">sql/uninstall.mysql.utf8.sql</file>
</sql>
</uninstall>
<update> <!-- Runs on update; New in 2.5 -->
<schemas>
<schemapath
type="mysql">sql/updates/mysql</schemapath>
</schemas>
</update>
<!-- Site Main File Copy Section -->
<!-- Note the folder attribute: This attribute describes the folder
to copy FROM in the package to install therefore files copied
in this section are copied from /site/ in the package -->
<files folder="site">
<filename>index.html</filename>
63
language/en-GB/en-GB.ini
media/index.html
media/images/index.html
media/images/tux-16x16.png
media/images/tux-48x48.png
64
<filename>helloworld.php</filename>
<filename>controller.php</filename>
<folder>views</folder>
<folder>models</folder>
<folder>language</folder>
</files>
Contents
<administration>
<!-- Administration Menu Section -->
<menu img="../media/com_helloworld/images/tux16x16.png">COM_HELLOWORLD_MENU</menu>
<!-- Administration Main File Copy Section -->
<!-- Note the folder attribute: This attribute describes the
folder
to copy FROM in the package to install therefore
files copied
in this section are copied from /admin/ in the
package -->
<files folder="admin">
<!-- Admin Main File Copy Section -->
<filename>index.html</filename>
<filename>helloworld.php</filename>
<filename>controller.php</filename>
<!-- SQL files section -->
<folder>sql</folder>
<!-- tables files section -->
<folder>tables</folder>
<!-- models files section -->
<folder>models</folder>
<!-- views files section -->
<folder>views</folder>
<!-- controllers files section -->
<folder>controllers</folder>
</files>
[Expand]
Introduction
This tutorial is part of the Developing a Model-View-Controller (MVC) Component for
Joomla!2.5 tutorial. You are encouraged to read the previous parts of the tutorial before reading
this.
See Form validation for some more general info on form validation (rules).
<languages folder="admin">
<language tag="en-GB">language/en-GB/enGB.com_helloworld.ini</language>
<language tag="en-GB">language/en-GB/enGB.com_helloworld.sys.ini</language>
</languages>
</administration>
</extension>
66
65
1 Introduction
2 Verifying the form (client side)
3 Verifying the form (server side)
4 Packaging the component
5 Navigate
6 Contributors
<fieldset class="adminform">
<legend><?php echo JText::_(
'COM_HELLOWORLD_HELLOWORLD_DETAILS' ); ?></legend>
<?php foreach($this->form->getFieldset() as $field): ?>
<?php if (!$field->hidden): ?>
<?php echo $field->label; ?>
<?php endif; ?>
<?php echo $field->input; ?>
<?php endforeach; ?>
</fieldset>
<div>
<input type="hidden" name="task" value="helloworld.edit" />
<?php echo JHtml::_('form.token'); ?>
</div>
</form>
admin/models/forms/helloworld.js
window.addEvent('domready', function() {
document.formvalidator.setHandler('greeting',
function (value) {
regex=/^[^0-9]+$/;
return regex.test(value);
});
});
It adds a handler to the form validator of Joomla for fields having the "validate-greeting" css
class. Each time the greeting field is modified, the handler will be executed to verify its validity
(no digits).
The final step is to verify the form when the save button is clicked.
You may have noted that the html form contained in the admin/views/helloworld/tmpl/edit.php
file now has the form-validate css class. And that we added a
JHTML::_('behavior.formvalidation'); call to tell Joomla to use its javascript form validation.
With your favorite file manager and editor put a file admin/views/helloworld/submitbutton.js
containing
admin/views/helloworld/submitbutton.js
Modify the admin/models/forms/helloworld.xml file to indicate that the greeting field has to be
verified:
<?xml version="1.0" encoding="utf-8"?>
<form
addrulepath="/administrator/components/com_helloworld/models/rules"
>
<fieldset>
<field
name="id"
type="hidden"
/>
<field
name="greeting"
type="text"
label="COM_HELLOWORLD_HELLOWORLD_GREETING_LABEL"
description="COM_HELLOWORLD_HELLOWORLD_GREETING_DESC"
size="40"
class="inputbox validate-greeting"
validate="greeting"
required="true"
default=""
/>
</fieldset>
</form>
Joomla.submitbutton = function(task)
{
if (task == '')
{
return false;
}
else
{
var isValid=true;
var action = task.split('.');
if (action[1] != 'cancel' && action[1] != 'close')
{
var forms = $$('form.form-validate');
for (var i=0;i<forms.length;i++)
{
if
(!document.formvalidator.isValid(forms[i]))
{
isValid = false;
break;
}
}
}
if (isValid)
{
Joomla.submitform(task);
return true;
}
else
{
Note for the moment that the css class is now "inputbox validate-greeting" and that the attribute
required is set to true. It means that this field is required and has to be verified by a handler of
the form validator framework of Joomla
With your favorite file manager and editor put a file admin/models/forms/helloworld.js
containing
alert(Joomla.JText._('COM_HELLOWORLD_HELLOWORLD_ERROR_UNACCEPTABLE',
67
68
$this->setDocument();
unacceptable'));
}
return false;
}
/**
* Setting the toolbar
*/
protected function addToolBar()
{
$input = JFactory::getApplication()->input;
$input->set('hidemainmenu', true);
$isNew = ($this->item->id == 0);
JToolBarHelper::title($isNew ?
JText::_('COM_HELLOWORLD_MANAGER_HELLOWORLD_NEW')
:
JText::_('COM_HELLOWORLD_MANAGER_HELLOWORLD_EDIT'), 'helloworld');
JToolBarHelper::save('helloworld.save');
JToolBarHelper::cancel('helloworld.cancel', $isNew ?
'JTOOLBAR_CANCEL' : 'JTOOLBAR_CLOSE');
}
/**
* Method to set up the document properties
*
* @return void
*/
protected function setDocument()
{
$isNew = ($this->item->id < 1);
$document = JFactory::getDocument();
$document->setTitle($isNew ?
JText::_('COM_HELLOWORLD_HELLOWORLD_CREATING')
:
JText::_('COM_HELLOWORLD_HELLOWORLD_EDITING'));
$document->addScript(JURI::root() . $this->script);
$document->addScript(JURI::root() .
"/administrator/components/com_helloworld"
.
"/views/helloworld/submitbutton.js");
}
}
This function will verify that all forms which have the "form-validate" css class are valid. Note
that it will display an alert message translated by the Joomla framework.
The HelloWorldViewHelloWorld view class has to be modified to use these javascript files:
admin/views/helloworld/view.html.php
<?php
// No direct access to this file
defined('_JEXEC') or die('Restricted access');
// import Joomla view library
jimport('joomla.application.component.view');
/**
* HelloWorld View
*/
class HelloWorldViewHelloWorld extends JView
{
/**
* display method of Hello view
* @return void
*/
public function display($tpl = null)
{
// get the Data
$form = $this->get('Form');
$item = $this->get('Item');
$script = $this->get('Script');
JText::script('COM_HELLOWORLD_HELLOWORLD_ERROR_UNACCEPTABLE');
}
}
admin/models/helloworld.php
<?php
// No direct access to this file
69
70
Note there is no function here - this is inherited from JFormRule (located in:
libraries/joomla/form /rule.php). All that is needed is the regex string to test against.
71
72
helloworld.xml
site/index.html
site/helloworld.php
site/controller.php
site/views/index.html
site/views/helloworld/index.html
site/views/helloworld/view.html.php
site/views/helloworld/tmpl/index.html
site/views/helloworld/tmpl/default.xml
site/views/helloworld/tmpl/default.php
site/models/index.html
site/models/helloworld.php
site/language/index.html
site/language/en-GB/index.html
site/language/en-GB/en-GB.com_helloworld.ini
admin/index.html
admin/helloworld.php
admin/controller.php
admin/sql/index.html
admin/sql/install.mysql.utf8.sql
admin/sql/uninstall.mysql.utf8.sql
admin/sql/updates/index.html
admin/sql/updates/mysql/index.html
admin/sql/updates/mysql/0.0.1.sql
admin/sql/updates/mysql/0.0.6.sql
admin/models/index.html
admin/models/fields/index.html
admin/models/fields/helloworld.php
admin/models/forms/index.html
admin/models/forms/helloworld.xml
admin/models/forms/helloworld.js
admin/models/rules/index.html
admin/models/rules/greeting.php
admin/models/helloworld.php
admin/models/helloworlds.php
admin/views/index.html
admin/views/helloworlds/index.html
admin/views/helloworlds/view.html.php
admin/views/helloworlds/tmpl/index.html
admin/views/helloworlds/tmpl/default.php
admin/views/helloworlds/tmpl/default_head.php
admin/views/helloworlds/tmpl/default_body.php
Create a compressed file of this directory or directly download the archive and install it using the
extension manager of Joomla. You can add a menu item of this component using the menu
manager in the backend.
helloworld.xml
<?xml version="1.0" encoding="utf-8"?>
<extension type="component" version="2.5.0" method="upgrade">
<name>COM_HELLOWORLD</name>
<!-- The following elements are optional and free of formatting
constraints -->
<creationDate>November 2009</creationDate>
<author>John Doe</author>
<authorEmail>[email protected]</authorEmail>
<authorUrl>http://www.example.org</authorUrl>
<copyright>Copyright Info</copyright>
<license>License Info</license>
<!-- The version string is recorded in the components table -->
<version>0.0.11</version>
<!-- The description is optional and defaults to the name -->
<description>COM_HELLOWORLD_DESCRIPTION</description>
<install> <!-- Runs on install -->
<sql>
<file driver="mysql"
charset="utf8">sql/install.mysql.utf8.sql</file>
</sql>
</install>
<uninstall> <!-- Runs on uninstall -->
<sql>
73
admin/views/helloworlds/tmpl/default_foot.php
admin/views/helloworld/index.html
admin/views/helloworld/view.html.php
admin/views/helloworld/submitbutton.js
admin/views/helloworld/tmpl/index.html
admin/views/helloworld/tmpl/edit.php
admin/tables/index.html
admin/tables/helloworld.php
admin/language/en-GB/en-GB.com_helloworld.ini
admin/language/en-GB/en-GB.com_helloworld.sys.ini
admin/controllers/index.html
admin/controllers/helloworld.php
admin/controllers/helloworlds.php
language/en-GB/en-GB.ini
media/index.html
media/images/index.html
media/images/tux-16x16.png
media/images/tux-48x48.png
74
<file driver="mysql"
charset="utf8">sql/uninstall.mysql.utf8.sql</file>
</sql>
</uninstall>
<update> <!-- Runs on update; New in 2.5 -->
<schemas>
<schemapath
type="mysql">sql/updates/mysql</schemapath>
</schemas>
</update>
<languages folder="admin">
<language tag="en-GB">language/en-GB/enGB.com_helloworld.ini</language>
<language tag="en-GB">language/en-GB/enGB.com_helloworld.sys.ini</language>
</languages>
</administration>
</extension>
Contents
<administration>
<!-- Administration Menu Section -->
<menu img="../media/com_helloworld/images/tux16x16.png">COM_HELLOWORLD_MENU</menu>
<!-- Administration Main File Copy Section -->
<!-- Note the folder attribute: This attribute describes the
folder
to copy FROM in the package to install therefore
files copied
in this section are copied from /admin/ in the
package -->
<files folder="admin">
<!-- Admin Main File Copy Section -->
<filename>index.html</filename>
<filename>helloworld.php</filename>
<filename>controller.php</filename>
<!-- SQL files section -->
<folder>sql</folder>
<!-- tables files section -->
<folder>tables</folder>
<!-- models files section -->
<folder>models</folder>
<!-- views files section -->
<folder>views</folder>
<!-- controllers files section -->
<folder>controllers</folder>
</files>
[Expand]
Introduction
This tutorial is part of the Developing a Model-View-Controller (MVC) Component for
Joomla!2.5 tutorial. You are encouraged to read the previous parts of the tutorial before reading
this.
76
75
1 Introduction
2 Modifying the SQL
3 Modifying the form
4 Modifying the menu type
5 Managing the submenu
6 Adding some ACL
7 Adding some translation strings
8 Packaging the component
9 Zips
10 Navigate
11 Contributors
The Joomla framework has implemented the use of categories for all components. Adding
categorized ability to a component is fairly simple.
description="COM_HELLOWORLD_HELLOWORLD_FIELD_GREETING_DESC"
size="40"
class="inputbox validate-greeting"
validate="greeting"
required="true"
default=""
/>
<field
name="catid"
type="category"
extension="com_helloworld"
class="inputbox"
default=""
label="COM_HELLOWORLD_HELLOWORLD_FIELD_CATID_LABEL"
description="COM_HELLOWORLD_HELLOWORLD_FIELD_CATID_DESC"
required="true"
>
<option value="0">JOPTION_SELECT_CATEGORY</option>
</field>
</fieldset>
</form>
admin/sql/updates/mysql/0.0.12.sql
ALTER TABLE `#__helloworld` ADD `catid` int(11) NOT NULL DEFAULT '0'
A HelloWorld message can now belong to a category. We have to modify the editing form. In
the admin/models/forms/helloworld.xml file, put these lines:
admin/models/fields/helloworld.php
admin/models/forms/helloworld.xml
<?php
// No direct access to this file
defined('_JEXEC') or die;
label="COM_HELLOWORLD_HELLOWORLD_FIELD_GREETING_LABEL"
77
78
/**
* Method to get a list of options for a list input.
*
* @return
array
An array of JHtml options.
*/
protected function getOptions()
{
$db = JFactory::getDBO();
JSubMenuHelper::addEntry(JText::_('COM_HELLOWORLD_SUBMENU_MESSAGES'),
'index.php?option=com_helloworld',
$submenu == 'messages');
JSubMenuHelper::addEntry(JText::_('COM_HELLOWORLD_SUBMENU_CATEGORIES'),
$query->select('#__helloworld.id as
id,greeting,#__categories.title as category,catid');
$query->from('#__helloworld');
$query->leftJoin('#__categories on catid=#__categories.id');
$db->setQuery((string)$query);
$messages = $db->loadObjectList();
$options = array();
if ($messages)
{
foreach($messages as $message)
{
$options[] = JHtml::_('select.option',
$message->id, $message->greeting .
($message->catid ? ' ('
. $message->category . ')' : ''));
}
}
$options = array_merge(parent::getOptions(), $options);
return $options;
}
}
'index.php?option=com_categories&view=categories&extension=com_helloworld',
$submenu == 'categories');
// set some global property
$document = JFactory::getDocument();
$document->addStyleDeclaration('.icon-48-helloworld ' .
'{background-image:
url(../media/com_helloworld/images/tux-48x48.png);}');
if ($submenu == 'categories')
{
$document>setTitle(JText::_('COM_HELLOWORLD_ADMINISTRATION_CATEGORIES'));
}
}
}
NOTE: You MUST use your component name (without com_) for the helper file name, or else
your submenus won't show in category view.
This function will be automatically called by the com_categories component. Note that it will
We have to change the general controller to call this function and modify the component entry
point (the .icon-48-helloworld css class is now set in the addSubmenu function)
The com_categories component allows to set the submenu using a helper file. With your favorite
file manager and editor, put a admin/helpers/helloworld.php file containing these lines:
admin/helpers/helloworld.php
admin/controller.php
<?php
// No direct access to this file
defined('_JEXEC') or die('Restricted access');
<?php
// No direct access to this file
defined('_JEXEC') or die;
/**
* HelloWorld component helper.
*/
/**
* General Controller of HelloWorld component
79
80
*/
class HelloWorldController extends JController
{
/**
* display task
*
* @return void
*/
public function display($cachable = false, $urlparams = false)
{
// set default view if not set
$input = JFactory::getApplication()->input;
$input->set('view', $input->getCmd('view', 'HelloWorlds'));
}
}
admin/access.xml
admin/language/en-GB/en-GB.com_helloworld.ini
NOTE: If you don't add this file, buttons "New" "Edit" and ... don't show in category view . for
more information read section Adding ACL on top of the page.
COM_HELLOWORLD="Hello World!"
COM_HELLOWORLD_ADMINISTRATION="HelloWorld - Administration"
COM_HELLOWORLD_ADMINISTRATION_CATEGORIES="HelloWorld - Categories"
COM_HELLOWORLD_HELLOWORLD_CREATING="HelloWorld - Creating"
COM_HELLOWORLD_HELLOWORLD_DETAILS="Details"
COM_HELLOWORLD_HELLOWORLD_EDITING="HelloWorld - Editing"
COM_HELLOWORLD_HELLOWORLD_ERROR_UNACCEPTABLE="Some values are unacceptable"
COM_HELLOWORLD_HELLOWORLD_FIELD_CATID_DESC="The category the messages belongs
to"
COM_HELLOWORLD_HELLOWORLD_FIELD_CATID_LABEL="Category"
COM_HELLOWORLD_HELLOWORLD_FIELD_GREETING_DESC="This message will be
displayed"
COM_HELLOWORLD_HELLOWORLD_FIELD_GREETING_LABEL="Message"
COM_HELLOWORLD_HELLOWORLD_HEADING_GREETING="Greeting"
COM_HELLOWORLD_HELLOWORLD_HEADING_ID="Id"
COM_HELLOWORLD_MANAGER_HELLOWORLD_EDIT="HelloWorld manager: Edit Message"
COM_HELLOWORLD_MANAGER_HELLOWORLD_NEW="HelloWorld manager: New Message"
COM_HELLOWORLD_MANAGER_HELLOWORLDS="HelloWorld manager"
COM_HELLOWORLD_N_ITEMS_DELETED_1="One message deleted"
COM_HELLOWORLD_N_ITEMS_DELETED_MORE="%d messages deleted"
COM_HELLOWORLD_SUBMENU_MESSAGES="Messages"
COM_HELLOWORLD_SUBMENU_CATEGORIES="Categories"
admin/helloworld.php
<?php
82
helloworld.xml
site/index.html
site/helloworld.php
site/controller.php
site/views/index.html
site/views/helloworld/index.html
site/views/helloworld/view.html.php
site/views/helloworld/tmpl/index.html
site/views/helloworld/tmpl/default.xml
site/views/helloworld/tmpl/default.php
site/models/index.html
site/models/helloworld.php
site/language/index.html
site/language/en-GB/index.html
site/language/en-GB/en-GB.com_helloworld.ini
admin/index.html
admin/helloworld.php
admin/controller.php
admin/access.xml
admin/sql/index.html
admin/sql/install.mysql.utf8.sql
admin/sql/uninstall.mysql.utf8.sql
admin/sql/updates/index.html
admin/sql/updates/mysql/index.html
admin/sql/updates/mysql/0.0.1.sql
admin/sql/updates/mysql/0.0.6.sql
admin/sql/updates/mysql/0.0.12.sql
admin/models/index.html
admin/models/fields/index.html
admin/models/fields/helloworld.php
admin/models/forms/index.html
admin/models/forms/helloworld.xml
admin/models/forms/helloworld.js
admin/models/rules/index.html
admin/models/rules/greeting.php
admin/models/helloworld.php
admin/models/helloworlds.php
admin/views/index.html
admin/views/helloworlds/index.html
admin/views/helloworlds/view.html.php
admin/views/helloworlds/tmpl/index.html
admin/views/helloworlds/tmpl/default.php
admin/views/helloworlds/tmpl/default_head.php
admin/views/helloworlds/tmpl/default_body.php
admin/views/helloworlds/tmpl/default_foot.php
admin/views/helloworlds/index.html
Create a compressed file of this directory or directly download the archive and install it using the
extension manager of Joomla. You can add a menu item of this component using the menu
manager in the backend.
helloworld.xml
<?xml version="1.0" encoding="utf-8"?>
<extension type="component" version="2.5.0" method="upgrade">
<name>COM_HELLOWORLD</name>
<!-- The following elements are optional and free of formatting
constraints -->
<creationDate>November 2009</creationDate>
<author>John Doe</author>
<authorEmail>[email protected]</authorEmail>
<authorUrl>http://www.example.org</authorUrl>
<copyright>Copyright Info</copyright>
<license>License Info</license>
<!-- The version string is recorded in the components table -->
<version>0.0.12</version>
<!-- The description is optional and defaults to the name -->
<description>COM_HELLOWORLD_DESCRIPTION</description>
<install> <!-- Runs on install -->
<sql>
<file driver="mysql"
charset="utf8">sql/install.mysql.utf8.sql</file>
</sql>
</install>
<uninstall> <!-- Runs on uninstall -->
<sql>
83
admin/views/helloworld/view.html.php
admin/views/helloworld/submitbutton.js
admin/views/helloworld/tmpl/index.html
admin/views/helloworld/tmpl/edit.php
admin/helpers/index.html
admin/helpers/helloworld.php
admin/tables/index.html
admin/tables/helloworld.php
admin/language/en-GB/en-GB.com_helloworld.ini
admin/language/en-GB/en-GB.com_helloworld.menu.ini
admin/controllers/index.html
admin/controllers/helloworld.php
admin/controllers/helloworldlist.php
language/en-GB/en-GB.ini
media/index.html
media/images/index.html
media/images/tux-16x16.png
media/images/tux-48x48.png
84
<file driver="mysql"
charset="utf8">sql/uninstall.mysql.utf8.sql</file>
</sql>
</uninstall>
<update> <!-- Runs on update; New in 2.5 -->
<schemas>
<schemapath
type="mysql">sql/updates/mysql</schemapath>
</schemas>
</update>
<folder>controllers</folder>
<!-- helpers files section -->
<folder>helpers</folder>
</files>
<languages folder="admin">
<language tag="en-GB">language/en-GB/enGB.com_helloworld.ini</language>
<language tag="en-GB">language/en-GB/enGB.com_helloworld.sys.ini</language>
</languages>
</administration>
</extension>
Contents
<administration>
<!-- Administration Menu Section -->
<menu img="../media/com_helloworld/images/tux16x16.png">COM_HELLOWORLD_MENU</menu>
<!-- Administration Main File Copy Section -->
<!-- Note the folder attribute: This attribute describes the
folder
to copy FROM in the package to install therefore
files copied
in this section are copied from /admin/ in the
package -->
<files folder="admin">
<!-- Admin Main File Copy Section -->
<filename>index.html</filename>
<filename>helloworld.php</filename>
<filename>controller.php</filename>
<!-- WARNING <filename>access.php</filename> has an incorrect file
extension, should be corrected in the ZIP-file -->
<filename>access.xml</filename>
<!-- SQL files section -->
<folder>sql</folder>
<!-- tables files section -->
<folder>tables</folder>
<!-- models files section -->
<folder>models</folder>
<!-- views files section -->
<folder>views</folder>
<!-- controllers files section -->
[Expand]
Introduction
86
85
1 Introduction
2 Adding configuration parameters
3 Using configuration parameters as default value
4 Modifying the SQL
5 Modifying the backend
6 Modifying the frontend
7 Adding some translation strings
8 Packaging the component
9 Navigate
10 Contributors
*/
class HelloWorldViewHelloWorlds extends JView
{
/**
* HelloWorlds view display method
* @return void
*/
function display($tpl = null)
{
// Get data from the model
$items = $this->get('Items');
$pagination = $this->get('Pagination');
// Check for errors.
if (count($errors = $this->get('Errors')))
{
JError::raiseError(500, implode('<br />', $errors));
return false;
}
// Assign data to the view
$this->items = $items;
$this->pagination = $pagination;
label="COM_HELLOWORLD_HELLOWORLD_FIELD_SHOW_CATEGORY_LABEL"
// Display the template
parent::display($tpl);
description="COM_HELLOWORLD_HELLOWORLD_FIELD_SHOW_CATEGORY_DESC"
default="0"
>
<option value="0">JHIDE</option>
<option value="1">JSHOW</option>
</field>
</fieldset>
</config>
This file will be read by the com_config component of the Joomla core. For the moment, we
defined only one parameter: is the category title displayed or not in the frontend?.
JToolBarHelper::title(JText::_('COM_HELLOWORLD_MANAGER_HELLOWORLDS'),
'helloworld');
JToolBarHelper::deleteListX('', 'helloworlds.delete');
JToolBarHelper::editListX('helloworld.edit');
JToolBarHelper::addNewX('helloworld.add');
JToolBarHelper::preferences('com_helloworld');
}
/**
* Method to set up the document properties
*
* @return void
*/
protected function setDocument()
{
$document = JFactory::getDocument();
$document>setTitle(JText::_('COM_HELLOWORLD_ADMINISTRATION'));
}
The best way to set the parameters is to put a Preferences button in a toolbar.
With your favorite editor, put these lines in admin/views/helloworlds/view.html.php
admin/views/helloworlds/view.html.php
<?php
// No direct access to this file
defined('_JEXEC') or die('Restricted access');
// import Joomla view library
jimport('joomla.application.component.view');
/**
* HelloWorlds View
87
88
}
label="COM_HELLOWORLD_HELLOWORLD_FIELD_SHOW_CATEGORY_LABEL"
description="COM_HELLOWORLD_HELLOWORLD_FIELD_SHOW_CATEGORY_DESC"
default=""
>
<option value="">JGLOBAL_USE_GLOBAL</option>
<option value="0">JHIDE</option>
<option value="1">JSHOW</option>
</field>
</fieldset>
</fields>
</form>
We define the same parameter for each message with an additional value: Use global.
label="COM_HELLOWORLD_HELLOWORLD_FIELD_GREETING_LABEL"
admin/sql/install.mysql.utf8.sql
description="COM_HELLOWORLD_HELLOWORLD_FIELD_GREETING_DESC"
size="40"
class="inputbox validate-greeting"
validate="greeting"
required="true"
default=""
/>
<field
name="catid"
type="category"
extension="com_helloworld"
class="inputbox"
default=""
label="COM_HELLOWORLD_HELLOWORLD_FIELD_CATID_LABEL"
description="COM_HELLOWORLD_HELLOWORLD_FIELD_CATID_DESC"
required="true"
>
<option value="0">JOPTION_SELECT_CATEGORY</option>
</field>
</fieldset>
<fields name="params">
<fieldset
name="params"
label="JGLOBAL_FIELDSET_DISPLAY_OPTIONS"
>
<field
name="show_category"
type="list"
admin/sql/updates/mysql/0.0.13.sql
ALTER TABLE `#__helloworld` ADD `params` VARCHAR(1024) NOT NULL DEFAULT '';
The TableHelloWorld has to be modified in order to deal with these parameters: they will be
stored in a JSON format and get in a JParameter class. We have to overload the bind and the
load method. With your favorite editor, put these lines into admin/tables/helloworld.php
admin/tables/helloworld.php
<?php
89
90
// No direct access
defined('_JEXEC') or die('Restricted access');
// $params->loadString($this->item->params, 'JSON');
// "item" should not be present.
$params->loadJSON($this->params);
$this->params = $params;
return true;
/**
* Hello Table class
*/
class HelloWorldTableHelloWorld extends JTable
{
/**
* Constructor
*
* @param object Database connector object
*/
function __construct(&$db)
{
parent::__construct('#__helloworld', 'id', $db);
}
/**
* Overloaded bind function
*
* @param
array
named array
* @return
null|string
null is operation was satisfactory,
otherwise returns an error
* @see JTable:bind
* @since 1.5
*/
public function bind($array, $ignore = '')
{
if (isset($array['params']) && is_array($array['params']))
{
// Convert the params field to a string.
$parameter = new JRegistry;
$parameter->loadArray($array['params']);
$array['params'] = (string)$parameter;
}
return parent::bind($array, $ignore);
}
}
else
{
return false;
}
}
}
/**
* Overloaded load function
*
* @param
int $pk primary key
* @param
boolean $reset reset data
* @return
boolean
* @see JTable:load
*/
public function load($pk = null, $reset = true)
{
if (parent::load($pk, $reset))
{
// Convert the params field to a registry.
$params = new JRegistry;
// loadJSON is @deprecated
12.1 Use loadString
passing JSON as the format instead.
91
92
protected $item;
/**
* Method to auto-populate the model state.
*
* This method should only be called once per instantiation and is
designed
* to be called on the first call to the getState() method unless the
model
* configuration flag to ignore the request is set.
*
* Note. Calling getState in this method will result in recursion.
*
* @return
void
* @since
2.5
*/
protected function populateState()
{
$app = JFactory::getApplication();
// Get the message id
$input = JFactory::getApplication()->input;
$id = $input->getInt('id');
$this->setState('message.id', $id);
/**
* Returns a reference to the a Table object, always creating it.
*
* @param
type
The table type to instantiate
* @param
string A prefix for the table class name. Optional.
* @param
array
Configuration array for model. Optional.
* @return
JTable A database object
* @since
2.5
*/
public function getTable($type = 'HelloWorld', $prefix =
'HelloWorldTable', $config = array())
{
return JTable::getInstance($type, $prefix, $config);
}
With your favorite editor, put these lines into the site/models/helloworld.php file:
site/models/helloworld.php
<?php
// No direct access to this file
defined('_JEXEC') or die('Restricted access');
/**
* Get the message
* @return object The message to be displayed to the user
*/
public function getItem()
{
if (!isset($this->item))
{
$id = $this->getState('message.id');
$this->_db->setQuery($this->_db->getQuery(true)
->from('#__helloworld as h')
93
94
->leftJoin('#__categories as c ON
h.catid=c.id')
}
// Display the view
parent::display($tpl);
->where('h.id=' . (int)$id));
if (!$this->item = $this->_db->loadObject())
{
$this->setError($this->_db->getError());
}
else
{
// Load the JSON string
$params = new JRegistry;
// loadJSON is @deprecated
12.1 Use
loadString passing JSON as the format instead.
//$params->loadString($this->item->params,
'JSON');
$params->loadJSON($this->item->params);
$this->item->params = $params;
}
}
The layout can now display correctly the category or not. With your favorite editor, put these
lines into site/views/helloworld/tmpl/default.php
site/views/helloworld/tmpl/default.php
<?php
// No direct access to this file
defined('_JEXEC') or die('Restricted access');
?>
<h1><?php echo $this->item->greeting.(($this->item->category and $this->item>params->get('show_category'))
? (' ('.$this->item->category.')') :
''); ?>
</h1>
}
}
admin/language/en-GB/en-GB.com_helloworld.ini
COM_HELLOWORLD="Hello World!"
COM_HELLOWORLD_ADMINISTRATION="HelloWorld - Administration"
COM_HELLOWORLD_ADMINISTRATION_CATEGORIES="HelloWorld - Categories"
COM_HELLOWORLD_HELLOWORLD_CREATING="HelloWorld - Creating"
COM_HELLOWORLD_HELLOWORLD_DETAILS="Details"
COM_HELLOWORLD_HELLOWORLD_EDITING="HelloWorld - Editing"
COM_HELLOWORLD_HELLOWORLD_ERROR_UNACCEPTABLE="Some values are unacceptable"
COM_HELLOWORLD_HELLOWORLD_FIELD_CATID_DESC="The category the messages belongs
to"
COM_HELLOWORLD_HELLOWORLD_FIELD_CATID_LABEL="Category"
COM_HELLOWORLD_HELLOWORLD_FIELD_GREETING_DESC="This message will be
displayed"
COM_HELLOWORLD_HELLOWORLD_FIELD_GREETING_LABEL="Message"
COM_HELLOWORLD_HELLOWORLD_FIELD_SHOW_CATEGORY_LABEL="Show category"
COM_HELLOWORLD_HELLOWORLD_FIELD_SHOW_CATEGORY_DESC="If set to Show, the title
of the message’s category will show."
COM_HELLOWORLD_HELLOWORLD_HEADING_GREETING="Greeting"
COM_HELLOWORLD_HELLOWORLD_HEADING_ID="Id"
COM_HELLOWORLD_MANAGER_HELLOWORLD_EDIT="HelloWorld manager: Edit Message"
COM_HELLOWORLD_MANAGER_HELLOWORLD_NEW="HelloWorld manager: New Message"
COM_HELLOWORLD_MANAGER_HELLOWORLDS="HelloWorld manager"
COM_HELLOWORLD_N_ITEMS_DELETED_1="One message deleted"
COM_HELLOWORLD_N_ITEMS_DELETED_MORE="%d messages deleted"
site/views/helloworld/view.html.php
<?php
// No direct access to this file
defined('_JEXEC') or die('Restricted access');
// import Joomla view library
jimport('joomla.application.component.view');
/**
* HTML View class for the HelloWorld Component
*/
class HelloWorldViewHelloWorld extends JView
{
// Overwriting JView display method
function display($tpl = null)
{
// Assign data to the view
$this->item = $this->get('Item');
// Check for errors.
if (count($errors = $this->get('Errors')))
95
96
COM_HELLOWORLD_SUBMENU_MESSAGES="Messages"
COM_HELLOWORLD_SUBMENU_CATEGORIES="Categories"
COM_HELLOWORLD_CONFIGURATION="HelloWorld Configuration"
COM_HELLOWORLD_CONFIG_GREETING_SETTINGS_LABEL="Messages settings"
COM_HELLOWORLD_CONFIG_GREETING_SETTINGS_DESC="Settings that will be applied
to all messages by default"
helloworld.xml
site/index.html
site/helloworld.php
site/controller.php
site/views/index.html
site/views/helloworld/index.html
site/views/helloworld/view.html.php
site/views/helloworld/tmpl/index.html
site/views/helloworld/tmpl/default.xml
site/views/helloworld/tmpl/default.php
site/models/index.html
site/models/helloworld.php
site/language/index.html
site/language/en-GB/index.html
site/language/en-GB/en-GB.com_helloworld.ini
admin/index.html
admin/config.xml
admin/helloworld.php
admin/controller.php
admin/sql/index.html
admin/sql/install.mysql.utf8.sql
admin/sql/uninstall.mysql.utf8.sql
admin/sql/updates/index.html
admin/sql/updates/mysql/index.html
admin/sql/updates/mysql/0.0.1.sql
admin/sql/updates/mysql/0.0.6.sql
admin/sql/updates/mysql/0.0.12.sql
admin/sql/updates/mysql/0.0.13.sql
admin/models/index.html
admin/models/fields/index.html
admin/models/fields/helloworld.php
admin/models/forms/index.html
admin/models/forms/helloworld.xml
admin/models/forms/helloworld.js
admin/models/rules/index.html
admin/models/rules/greeting.php
Create a compressed file of this directory or directly download the archive and install it using the
extension manager of Joomla!1.6. You can add a menu item of this component using the menu
manager in the backend.
helloworld.xml
<?xml version="1.0" encoding="utf-8"?>
<extension type="component" version="2.5.0" method="upgrade">
<name>COM_HELLOWORLD</name>
<!-- The following elements are optional and free of formatting
constraints -->
<creationDate>November 2009</creationDate>
<author>John Doe</author>
<authorEmail>[email protected]</authorEmail>
<authorUrl>http://www.example.org</authorUrl>
<copyright>Copyright Info</copyright>
<license>License Info</license>
<!-- The version string is recorded in the components table -->
97
admin/models/helloworld.php
admin/models/helloworlds.php
admin/views/index.html
admin/views/helloworlds/index.html
admin/views/helloworlds/view.html.php
admin/views/helloworlds/tmpl/index.html
admin/views/helloworlds/tmpl/default.php
admin/views/helloworlds/tmpl/default_head.php
admin/views/helloworlds/tmpl/default_body.php
admin/views/helloworlds/tmpl/default_foot.php
admin/views/helloworld/index.html
admin/views/helloworld/view.html.php
admin/views/helloworld/submitbutton.js
admin/views/helloworld/tmpl/index.html
admin/views/helloworld/tmpl/edit.php
admin/helpers/index.html
admin/helpers/helloworld.php
admin/tables/index.html
admin/tables/helloworld.php
admin/language/en-GB/en-GB.com_helloworld.ini
admin/language/en-GB/en-GB.com_helloworld.sys.ini
admin/controllers/index.html
admin/controllers/helloworld.php
admin/controllers/helloworlds.php
language/en-GB/en-GB.ini
media/index.html
media/images/index.html
media/images/tux-16x16.png
media/images/tux-48x48.png
98
<version>0.0.13</version>
<!-- The description is optional and defaults to the name -->
<description>COM_HELLOWORLD_DESCRIPTION</description>
<filename>controller.php</filename>
<!-- SQL files section -->
<folder>sql</folder>
<!-- tables files section -->
<folder>tables</folder>
<!-- models files section -->
<folder>models</folder>
<!-- views files section -->
<folder>views</folder>
<!-- controllers files section -->
<folder>controllers</folder>
<!-- helpers files section -->
<folder>helpers</folder>
</files>
<languages folder="admin">
<language tag="en-GB">language/en-GB/enGB.com_helloworld.ini</language>
<language tag="en-GB">language/en-GB/enGB.com_helloworld.sys.ini</language>
</languages>
</administration>
</extension>
Contents
<administration>
<!-- Administration Menu Section -->
<menu img="../media/com_helloworld/images/tux16x16.png">COM_HELLOWORLD_MENU</menu>
<!-- Administration Main File Copy Section -->
<!-- Note the folder attribute: This attribute describes the
folder
to copy FROM in the package to install therefore
files copied
in this section are copied from /admin/ in the
package -->
<files folder="admin">
<!-- Admin Main File Copy Section -->
<filename>index.html</filename>
<filename>config.xml</filename>
<filename>helloworld.php</filename>
100
99
1 Introduction
2 Adding Access Control
3 Minimal ACL requirements at the component level
o 3.1 Add the 2 minimal component level actions to access.xml
o 3.2 Add the permissions fieldset to config.xml
o 3.3 Add the 'Options' toolbar button when user is authorised for it
o 3.4 Restrict the access to the component's backend to authorised usergroups
4 Adding more actions, also at category level and item level
o 4.1 Describing the actions you want to control the access to
o 4.2 Adding the setting of permissions in the component's Preferences
o 4.3 Displaying only the right toolbar buttons
o 4.4 Restricting access to the component
o 4.5 Add the asset_id column to the database table
Configure (core.admin): which groups are allowed to configure the component level
permissions via the 'Options' toolbar button?
Access Component (core.manage): which groups are allowed to access the component's
backend?
[Expand]
Introduction
This tutorial is part of the Developing a Model-View-Controller (MVC) Component for
Joomla!2.5 tutorial. You are encouraged to read the previous parts of the tutorial before reading
this.
admin/access.xml
<?xml version="1.0" encoding="utf-8" ?>
<access component="com_helloworld">
<section name="component">
<action name="core.admin" title="JACTION_ADMIN"
description="JACTION_ADMIN_COMPONENT_DESC" />
<action name="core.manage" title="JACTION_MANAGE"
description="JACTION_MANAGE_COMPONENT_DESC" />
</section>
</access>
In this article we will show how to add and use access permissions at several levels of
granularity: for your component as a whole, for the categories and for the individual items.
101
102
/>
</fieldset>
See the more elaborate config.xml example further downwards for the exact place where to
insert this code.
See further downwards for the whole code of the admin/helloworld.php file.
Add the actions to access.xml; here we can add more actions and levels
Add the permissions-fieldset to config.xml
Add the 'Options' toolbar button
Restrict the access to the component's backend
admin/access.xml
<?xml version="1.0" encoding="utf-8" ?>
<access component="com_helloworld">
<section name="component">
<action name="core.admin" title="JACTION_ADMIN"
description="JACTION_ADMIN_COMPONENT_DESC" />
<action name="core.manage" title="JACTION_MANAGE"
description="JACTION_MANAGE_COMPONENT_DESC" />
<action name="core.create" title="JACTION_CREATE"
description="JACTION_CREATE_COMPONENT_DESC" />
<action name="core.delete" title="JACTION_DELETE"
description="JACTION_DELETE_COMPONENT_DESC" />
<action name="core.edit" title="JACTION_EDIT"
description="JACTION_EDIT_COMPONENT_DESC" />
</section>
<section name="category">
<action name="core.create" title="JACTION_CREATE"
description="COM_CATEGORIES_ACCESS_CREATE_DESC" />
<action name="core.delete" title="JACTION_DELETE"
description="COM_CATEGORIES_ACCESS_DELETE_DESC" />
<action name="core.edit" title="JACTION_EDIT"
description="COM_CATEGORIES_ACCESS_EDIT_DESC" />
<action name="core.edit.state" title="JACTION_EDITSTATE"
description="COM_CATEGORIES_ACCESS_EDITSTATE_DESC" />
<action name="core.edit.own" title="JACTION_EDITOWN"
description="COM_CATEGORIES_ACCESS_EDITOWN_DESC" />
</section>
<section name="message">
<action name="core.delete" title="JACTION_DELETE"
description="COM_HELLOWORLD_ACCESS_DELETE_DESC" />
<action name="core.edit" title="JACTION_EDIT"
description="COM_HELLOWORLD_ACCESS_EDIT_DESC" />
</section>
</access>
Add an asset_id to the item's database table for item level access control
Store the permissions in the assets table. Especially take care of setting the asset_id of the
parent-asset
Since we now use Access Control permissions in our component, we need to be able to set them
at the component level. That is done in the Preferences of this component: the screen you see
after clicking the 'Options' button. The config.xml-file is a form-definition for those Preferences.
103
104
We could define the component level actions here too, as a child of the "rules" field-tag, but it is
now preferred to also put those actions in access.xml: in that way all access rules for this
component are on one spot.
admin/config.xml
<?xml version="1.0" encoding="utf-8"?>
<config>
<fieldset
name="greetings"
label="COM_HELLOWORLD_CONFIG_GREETING_SETTINGS_LABEL"
description="COM_HELLOWORLD_CONFIG_GREETING_SETTINGS_DESC"
>
<field
name="show_category"
type="radio"
* HelloWorlds View
*/
class HelloWorldViewHelloWorlds extends JViewLegacy
{
protected $items;
protected $pagination;
protected $canDo;
/**
* HelloWorlds view display method
* @return void
*/
function display($tpl = null)
{
// Get data from the model
$this->items = $this->get('Items');
$this->pagination = $this->get('Pagination');
(s)he do?
label="COM_HELLOWORLD_HELLOWORLD_FIELD_SHOW_CATEGORY_LABEL"
description="COM_HELLOWORLD_HELLOWORLD_FIELD_SHOW_CATEGORY_DESC"
default="0"
>
<option value="0">JHIDE</option>
<option value="1">JSHOW</option>
</field>
</fieldset>
<fieldset
name="permissions"
label="JCONFIG_PERMISSIONS_LABEL"
description="JCONFIG_PERMISSIONS_DESC"
>
<field
name="rules"
type="rules"
label="JCONFIG_PERMISSIONS_LABEL"
class="inputbox"
validate="rules"
filter="rules"
component="com_helloworld"
section="component"
/>
</fieldset></config>
JToolBarHelper::title(JText::_('COM_HELLOWORLD_MANAGER_HELLOWORLDS'),
'helloworld');
if ($this->canDo->get('core.create'))
{
JToolBarHelper::addNew('helloworld.add', 'JTOOLBAR_NEW');
}
if ($this->canDo->get('core.edit'))
{
JToolBarHelper::editList('helloworld.edit',
'JTOOLBAR_EDIT');
}
if ($this->canDo->get('core.delete'))
{
JToolBarHelper::deleteList('', 'helloworlds.delete',
'JTOOLBAR_DELETE');
}
if ($this->canDo->get('core.admin'))
{
JToolBarHelper::divider();
JToolBarHelper::preferences('com_helloworld');
}
}
/**
105
106
(s)he do?
>item->id);
'JTOOLBAR_SAVE_AND_NEW', false);
}
JToolBarHelper::cancel('helloworld.cancel', 'JTOOLBAR_CANCEL');
}
else
{
if ($this->canDo->get('core.edit'))
{
// We can save the new record
JToolBarHelper::apply('helloworld.apply',
'JTOOLBAR_APPLY');
JToolBarHelper::save('helloworld.save',
'JTOOLBAR_SAVE');
'JTOOLBAR_SAVE_AND_NEW', false);
}
if ($this->canDo->get('core.create'))
107
}
{
108
JSubMenuHelper::addEntry(JText::_('COM_HELLOWORLD_SUBMENU_CATEGORIES'),
'JTOOLBAR_SAVE_AS_COPY', false);
}
JToolBarHelper::cancel('helloworld.cancel', 'JTOOLBAR_CLOSE');
}
}
/**
* Method to set up the document properties
*
* @return void
*/
protected function setDocument()
{
$isNew = $this->item->id == 0;
$document = JFactory::getDocument();
$document->setTitle($isNew ?
JText::_('COM_HELLOWORLD_HELLOWORLD_CREATING')
:
JText::_('COM_HELLOWORLD_HELLOWORLD_EDITING'));
$document->addScript(JURI::root() . $this->script);
$document->addScript(JURI::root() .
"/administrator/components/com_helloworld"
.
"/views/helloworld/submitbutton.js");
'index.php?option=com_categories&view=categories&extension=com_helloworld',
$submenu == 'categories');
// set some global property
$document = JFactory::getDocument();
$document->addStyleDeclaration('.icon-48-helloworld ' .
'{background-image:
url(../media/com_helloworld/images/tux-48x48.png);}');
if ($submenu == 'categories')
{
$document>setTitle(JText::_('COM_HELLOWORLD_ADMINISTRATION_CATEGORIES'));
}
}
/**
* Get the actions
*/
public static
function getActions($messageId = 0)
{
jimport('joomla.access.access');
$user
=
JFactory::getUser();
$result = new JObject;
if
(empty($messageId)) {
$assetName = 'com_helloworld';
}
else {
$assetName =
'com_helloworld.message.'.(int) $messageId;
}
$actions = JAccess::getActions('com_helloworld',
'component');
foreach ($actions as $action) {
$result->set($action->name, $user->authorise($action->name, $assetName));
}
return $result;
}}
JText::script('COM_HELLOWORLD_HELLOWORLD_ERROR_UNACCEPTABLE');
}
}
These two files use the getActions method defined in the admin/helpers/helloworld.php file
The main idea in ACL is to restrict actions to groups of users. The first action to be restricted is
access to the administrative backend of the component itself. With your favorite file editor, edit
the admin/helloworld.php file and add the lines with the access check.
admin/helloworld.php
<?php
// No direct access to this file
defined('_JEXEC') or die;
<?php
// No direct access to this file
defined('_JEXEC') or die('Restricted access');
/**
* HelloWorld component helper.
*/
abstract class HelloWorldHelper
{
/**
* Configure the Linkbar.
*/
public static function addSubmenu($submenu)
{
JSubMenuHelper::addEntry(JText::_('COM_HELLOWORLD_SUBMENU_MESSAGES'),
'index.php?option=com_helloworld',
$submenu == 'messages');
109
110
To check "core.edit" (and core.add if you wish) you need to update the sub-controller (not the
model). I am not sure why this is so, but that's how other standard Joomla components do it. You
need to add the following lines in the file: /admin/controllers/helloworld.php
/**
* Implement to allowAdd or not
*
* Not used at this time (but you can look at how other components use
it....)
* Overwrites: JControllerForm::allowAdd
*
* @param array $data
* @return bool
*/
protected function allowAdd($data = array())
{
return parent::allowAdd($data);
}
/**
* Implement to allow edit or not
* Overwrites: JControllerForm::allowEdit
*
* @param array $data
* @param string $key
* @return bool
*/
protected function allowEdit($data = array(), $key = 'id')
{
$id = isset( $data[ $key ] ) ? $data[ $key ] : 0;
if( !empty( $id ) ){
$user = JFactory::getUser();
return $user->authorise( "core.edit", "com_helloworld.message." .
$id );
}
}
Please note that allowAdd simply calls its parent. I've put it here in case you want to actually use
it in your component. If you look at your admin/access.xml file, you will notice there is no
core.add action defined for "messages", so you will need to add it there as well if you want to be
able to configure it in the interface.
112
JTable not only provides an interface for storing the data of the record itself in the item's
database table, but also for storing the permissions for that record in the assets database table.
Therefore we must add information to the bind()-method about the permission-values. We also
have to provide the asset name, asset title and the id of the asset parent via the helloworld JTable.
Therefore we override 3 methods:
admin/tables/helloworld.php
<?php
// No direct access
defined('_JEXEC') or die('Restricted access');
// import Joomla table library
jimport('joomla.database.table');
/**
* Method to compute the default name of the
asset.
* The default name is in the form `table_name.id`
*
where id is the value of the primary key of the table.
*
*
@return
string
* @since
2.5
*/
protected
function _getAssetName()
{
$k = $this->_tbl_key;
return 'com_helloworld.message.'.(int) $this->$k;
}
/**
* Method to return the title to use for the asset
table.
*
* @return
string
* @since
2.5
*/
protected function _getAssetTitle()
{
return $this->greeting;
}
/**
* Method to get the
asset-parent-id of the item
*
* @return
int
*/
protected function _getAssetParentId()
{
// We will
retrieve the parent-asset from the Asset-table
$assetParent =
JTable::getInstance('Asset');
// Default: if no asset-parent
can be found we take the global asset
$assetParentId =
$assetParent->getRootId();
// Find the parent-asset
if (($this->catid)&& !empty($this->catid))
{
// The item has a category as asset-parent
$assetParent->loadByName('com_helloworld.category.' . (int) $this->catid);
}
else
{
// The item has
the component as asset-parent
$assetParent>loadByName('com_helloworld');
}
// Return the
found asset-parent-id
if ($assetParent->id)
{
$assetParentId=$assetParent->id;
}
return
$assetParentId;
}}
/**
* Overridden bind function
*
* @param
array
named array
* @return
null|string
null if operation was satisfactory,
otherwise returns an error
* @see JTable:bind
* @since 1.5
*/
public function bind($array, $ignore = '')
{
if (isset($array['params']) && is_array($array['params']))
{
// Convert the params field to a string.
$parameter = new JRegistry;
$parameter->loadArray($array['params']);
$array['params'] = (string)$parameter;
}
113
if (isset($array['rules'])
$rules
$thisreturn
/**
* Overridden load function
*
* @param
int $pk primary key
* @param
boolean $reset reset data
* @return
boolean
* @see JTable:load
*/
public function load($pk = null, $reset = true)
{
if (parent::load($pk, $reset))
{
// Convert the params field to a registry.
$params = new JRegistry;
$params->loadJSON($this->params);
$this->params = $params;
return true;
}
else
{
return false;
}
}
/**
* Hello Table class
*/
class HelloWorldTableHelloWorld extends JTable
{
/**
* Constructor
*
* @param object Database connector object
*/
function __construct(&$db)
{
parent::__construct('#__helloworld', 'id', $db);
}
114
This code for _getAssetParentId() above uses JTableAsset to retrieve the asset_id of the assetparent. This is different from the code in the current version of com_content, where the asset_id
of the category is retrieved from the #__categories database table. That is another possibility;
many ways leading to Rome. In com_content however, if an item would not be under a category,
then the asset_id of the global asset is returned. That would of course not be right, but is fixed
there by providing a default category "uncategorised", so that an article is always under a
category. That is why you cannot just copy the code of _getAssetParentId() in com_content to
your own component. The code above is more general.
And display the ACL interface at the bottom of your Helloworld editform
admin/views/helloworld/tmpl/edit.php
<?php
// No direct access
defined('_JEXEC') or die('Restricted access');
JHtml::_('behavior.tooltip');
JHtml::_('behavior.formvalidation');
$params = $this->form->getFieldsets('params');
?>
<form action="<?php echo
JRoute::_('index.php?option=com_helloworld&layout=edit&id='.(int) $this>item->id); ?>"
method="post" name="adminForm" id="helloworld-form" class="formvalidate">
admin/language/en-GB/en-GB.com_helloworld.ini
COM_HELLOWORLD_FIELDSET_RULES="Message Permissions"
COM_HELLOWORLD_ACCESS_DELETE_DESC="Is this group allowed to edit this
message?"
115
116
Further reading
More information on actions, assets and ACL can be found on the following pages:
Deprecated classes
For the moment we leave the deprecated JError-references as they are. They will probably still
be available in Joomla! 3.x. We cannot just change them to JLog::add() statements because in
Joomla! 2.5 the messages will then not be enqueued (as there is no messagequeue-logger added
as is in /libraries/cms.php in Joomla! 3.0). Other solutions, like using $app->enqueueMessage()
or directly throwing PHP-exceptions as showstopper are also possible, but then there would still
be numerous references to JError throughout the application. For instance in the view, we now
check for errors raised in the model with: count($errors = $this->get('Errors')), which uses JError
from the JOBject that was the base for JModel. To get the same functionality without using
JError at all, we would have to change the way the Model raises those errors and warnings now.
If we want to make an application that would work in Joomla! 2.5 and 3.x we can continue using
JError. The moment we want to use our 3.x extensions also in 4.x we will have to change this
(and probably a lot more too). This tutorial is now primarily focussed on Joomla! 2.5. So: we
notice the upcoming change, but leave it there for the moment.
Since Joomla! 2.5.5 the MVC-base-classes JController, JModel and JView got proxies
JControllerLegacy, JModelLegacy and JViewLegacy. You are recommended to use those
proxies instead of the original classes to be forward compatibility with Joomla! CMS 3.x legacy
classes.
helloworld.xml
site/index.html
site/helloworld.php
site/controller.php
site/views/index.html
site/views/helloworld/index.html
site/views/helloworld/view.html.php
site/views/helloworld/tmpl/index.html
117
site/views/helloworld/tmpl/default.xml
site/views/helloworld/tmpl/default.php
site/models/index.html
site/models/helloworld.php
site/language/index.html
site/language/en-GB/index.html
site/language/en-GB/en-GB.com_helloworld.ini
admin/index.html
admin/access.xml
admin/config.xml
admin/helloworld.php
admin/controller.php
admin/sql/index.html
admin/sql/install.mysql.utf8.sql
admin/sql/uninstall.mysql.utf8.sql
admin/sql/updates/index.html
admin/sql/updates/mysql/index.html
admin/sql/updates/mysql/0.0.1.sql
admin/sql/updates/mysql/0.0.6.sql
admin/sql/updates/mysql/0.0.12.sql
admin/sql/updates/mysql/0.0.13.sql
admin/models/index.html
admin/models/fields/index.html
admin/models/fields/helloworld.php
admin/models/forms/index.html
admin/models/forms/helloworld.xml
admin/models/forms/helloworld.js
admin/models/rules/index.html
admin/models/rules/greeting.php
admin/models/helloworld.php
admin/models/helloworlds.php
admin/views/index.html
admin/views/helloworlds/index.html
admin/views/helloworlds/view.html.php
admin/views/helloworlds/tmpl/index.html
admin/views/helloworlds/tmpl/default.php
admin/views/helloworlds/tmpl/default_head.php
admin/views/helloworlds/tmpl/default_body.php
admin/views/helloworlds/tmpl/default_foot.php
admin/views/helloworld/index.html
admin/views/helloworld/view.html.php
admin/views/helloworld/submitbutton.js
admin/views/helloworld/tmpl/index.html
admin/views/helloworld/tmpl/edit.php
admin/helpers/index.html
admin/helpers/helloworld.php
118
</update>
admin/tables/index.html
admin/tables/helloworld.php
admin/language/en-GB/en-GB.com_helloworld.ini
admin/language/en-GB/en-GB.com_helloworld.sys.ini
admin/controllers/index.html
admin/controllers/helloworld.php
admin/controllers/helloworlds.php
language/en-GB/en-GB.ini
media/index.html
media/images/index.html
media/images/tux-16x16.png
media/images/tux-48x48.png
Create a compressed file of this directory or directly download the archive (TODO: zip has to be
updated! Will be done coming days...) and install it using the extension manager of Joomla. You
can add a menu item of this component using the menu manager in the backend.
<administration>
<!-- Administration Menu Section -->
<menu img="../media/com_helloworld/images/tux16x16.png">COM_HELLOWORLD_MENU</menu>
<!-- Administration Main File Copy Section -->
<!-- Note the folder attribute: This attribute describes the
folder
to copy FROM in the package to install therefore
files copied
in this section are copied from /admin/ in the
package -->
<files folder="admin">
<!-- Admin Main File Copy Section -->
<filename>index.html</filename>
<filename>config.xml</filename>
<filename>access.xml</filename>
<filename>helloworld.php</filename>
<filename>controller.php</filename>
<!-- SQL files section -->
<folder>sql</folder>
<!-- tables files section -->
<folder>tables</folder>
<!-- models files section -->
<folder>models</folder>
<!-- views files section -->
<folder>views</folder>
<!-- controllers files section -->
<folder>controllers</folder>
<!-- helpers files section -->
<folder>helpers</folder>
</files>
helloworld.xml
<?xml version="1.0" encoding="utf-8"?>
<extension type="component" version="2.5.0" method="upgrade">
<name>COM_HELLOWORLD</name>
<!-- The following elements are optional and free of formatting
constraints -->
<creationDate>November 2009</creationDate>
<author>John Doe</author>
<authorEmail>[email protected]</authorEmail>
<authorUrl>http://www.example.org</authorUrl>
<copyright>Copyright Info</copyright>
<license>License Info</license>
<!-- The version string is recorded in the components table -->
<version>0.0.14</version>
<!-- The description is optional and defaults to the name -->
<description>COM_HELLOWORLD_DESCRIPTION</description>
<install> <!-- Runs on install -->
<sql>
<file driver="mysql"
charset="utf8">sql/install.mysql.utf8.sql</file>
</sql>
</install>
<uninstall> <!-- Runs on uninstall -->
<sql>
<file driver="mysql"
charset="utf8">sql/uninstall.mysql.utf8.sql</file>
</sql>
</uninstall>
<update> <!-- Runs on update; New in 2.5 -->
<schemas>
<schemapath
type="mysql">sql/updates/mysql</schemapath>
</schemas>
<languages folder="admin">
<language tag="en-GB">language/en-GB/enGB.com_helloworld.ini</language>
<language tag="en-GB">language/en-GB/enGB.com_helloworld.sys.ini</language>
119
120
</languages>
</administration>
</extension>
/**
* Script file of HelloWorld component
*/
class com_helloWorldInstallerScript
{
/**
* method to install the component
*
* @return void
*/
function install($parent)
{
// $parent is the class calling this method
$parent->getParent()>setRedirectURL('index.php?option=com_helloworld');
}
Contents
update
uninstall
postflight which is executed after install and update
1 Introduction
2 Creating the extension script file
3 Adding some language keys
4 Packaging the component
5 Navigate
6 Contributors
[Expand]
/**
* method to uninstall the component
*
* @return void
*/
function uninstall($parent)
{
// $parent is the class calling this method
echo '<p>' . JText::_('COM_HELLOWORLD_UNINSTALL_TEXT') .
Introduction
This tutorial is part of the Developing a Model-View-Controller (MVC) Component for
Joomla!2.5 tutorial. You are encouraged to read the previous parts of the tutorial before reading
this.
'</p>';
}
/**
* method to update the component
*
* @return void
*/
function update($parent)
{
// $parent is the class calling this method
echo '<p>' . JText::sprintf('COM_HELLOWORLD_UPDATE_TEXT',
$parent->get('manifest')->version) . '</p>';
}
/**
121
122
note: If you want that these languages KEYs to be used at the first install of the component, the
sys.ini language file must be stored in the component folder (admin/language/en-GB/enGB.com_helloworld.sys.ini), and the xml manifest file must contains a folder tag for copying
language in the component folder. Modify your Manifest file accordingly:
/**
* method to run after an install/update/uninstall method
*
* @return void
*/
function postflight($type, $parent)
{
// $parent is the class calling this method
// $type is the type of change (install, update or
discover_install)
echo '<p>' . JText::_('COM_HELLOWORLD_POSTFLIGHT_' . $type .
'_TEXT') . '</p>';
}
}
<files folder="admin">
<!-- language folder -->
<folder>language</folder>
</files>
<languages folder="admin">
<language tag="en-GB">language/en-GB/enGB.com_helloworld.ini</language>
<!-- com_helloworld.sys.ini no longer needed there-->
</languages>
This script file will redirect the user to the com_helloworld component when it is installed and
will display messages when it is updated or uninstalled. In the update method we show the new
version using $parent->get('manifest')->version.
123
helloworld.xml
script.php
site/index.html
site/helloworld.php
site/controller.php
site/views/index.html
site/views/helloworld/index.html
site/views/helloworld/view.html.php
site/views/helloworld/tmpl/index.html
site/views/helloworld/tmpl/default.xml
site/views/helloworld/tmpl/default.php
site/models/index.html
site/models/helloworld.php
site/language/index.html
site/language/en-GB/index.html
site/language/en-GB/en-GB.com_helloworld.ini
admin/index.html
admin/access.xml
admin/config.xml
admin/helloworld.php
admin/controller.php
admin/sql/index.html
admin/sql/install.mysql.utf8.sql
124
admin/sql/uninstall.mysql.utf8.sql
admin/sql/updates/index.html
admin/sql/updates/mysql/index.html
admin/sql/updates/mysql/0.0.1.sql
admin/sql/updates/mysql/0.0.6.sql
admin/sql/updates/mysql/0.0.12.sql
admin/sql/updates/mysql/0.0.13.sql
admin/models/index.html
admin/models/fields/index.html
admin/models/fields/helloworld.php
admin/models/forms/index.html
admin/models/forms/helloworld.xml
admin/models/forms/helloworld.js
admin/models/rules/index.html
admin/models/rules/greeting.php
admin/models/helloworld.php
admin/models/helloworlds.php
admin/views/index.html
admin/views/helloworlds/index.html
admin/views/helloworlds/view.html.php
admin/views/helloworlds/tmpl/index.html
admin/views/helloworlds/tmpl/default.php
admin/views/helloworlds/tmpl/default_head.php
admin/views/helloworlds/tmpl/default_body.php
admin/views/helloworlds/tmpl/default_foot.php
admin/views/helloworld/index.html
admin/views/helloworld/view.html.php
admin/views/helloworld/submitbutton.js
admin/views/helloworld/tmpl/index.html
admin/views/helloworld/tmpl/edit.php
admin/helpers/index.html
admin/helpers/helloworld.php
admin/tables/index.html
admin/tables/helloworld.php
admin/language/en-GB/en-GB.com_helloworld.ini
admin/language/en-GB/en-GB.com_helloworld.sys.ini
admin/controllers/index.html
admin/controllers/helloworld.php
admin/controllers/helloworlds.php
language/en-GB/en-GB.ini
media/index.html
media/images/index.html
media/images/tux-16x16.png
media/images/tux-48x48.png
Create a compressed file of this directory or directly download the archive and install it using the
extension manager of Joomla. You can add a menu item of this component using the menu
manager in the backend.
helloworld.xml
<?xml version="1.0" encoding="utf-8"?>
<extension type="component" version="2.5.0" method="upgrade">
<name>COM_HELLOWORLD</name>
<!-- The following elements are optional and free of formatting
constraints -->
<creationDate>November 2009</creationDate>
<author>John Doe</author>
<authorEmail>[email protected]</authorEmail>
<authorUrl>http://www.example.org</authorUrl>
<copyright>Copyright Info</copyright>
<license>License Info</license>
<!-- The version string is recorded in the components table -->
<version>0.0.15</version>
<!-- The description is optional and defaults to the name -->
<description>COM_HELLOWORLD_DESCRIPTION</description>
<!-- Runs on install/uninstall/update; New in 2.5 -->
<scriptfile>script.php</scriptfile>
<install> <!-- Runs on install -->
<sql>
<file driver="mysql"
charset="utf8">sql/install.mysql.utf8.sql</file>
</sql>
</install>
<uninstall> <!-- Runs on uninstall -->
<sql>
<file driver="mysql"
charset="utf8">sql/uninstall.mysql.utf8.sql</file>
</sql>
</uninstall>
<update> <!-- Runs on update; New in 2.5 -->
<schemas>
<schemapath
type="mysql">sql/updates/mysql</schemapath>
</schemas>
</update>
<!-- Site Main File Copy Section -->
<!-- Note the folder attribute: This attribute describes the folder
to copy FROM in the package to install therefore files copied
in this section are copied from /site/ in the package -->
<files folder="site">
<filename>index.html</filename>
<filename>helloworld.php</filename>
<filename>controller.php</filename>
<folder>views</folder>
<folder>models</folder>
125
126
<folder>language</folder>
</files>
<media destination="com_helloworld" folder="media">
<filename>index.html</filename>
<folder>images</folder>
</media>
<administration>
<!-- Administration Menu Section -->
<menu img="../media/com_helloworld/images/tux16x16.png">COM_HELLOWORLD_MENU</menu>
<!-- Administration Main File Copy Section -->
<!-- Note the folder attribute: This attribute describes the
folder
to copy FROM in the package to install therefore
files copied
in this section are copied from /admin/ in the
package -->
<files folder="admin">
<!-- Admin Main File Copy Section -->
<filename>index.html</filename>
<filename>config.xml</filename>
<filename>access.xml</filename>
<filename>helloworld.php</filename>
<filename>controller.php</filename>
<!-- SQL files section -->
<folder>sql</folder>
<!-- tables files section -->
<folder>tables</folder>
<!-- models files section -->
<folder>models</folder>
<!-- views files section -->
<folder>views</folder>
<!-- controllers files section -->
<folder>controllers</folder>
<!-- helpers files section -->
<folder>helpers</folder>
</files>
<languages folder="admin">
<language tag="en-GB">language/en-GB/enGB.com_helloworld.ini</language>
<language tag="en-GB">language/en-GB/enGB.com_helloworld.sys.ini</language>
</languages>
</administration>
</extension>
127