Archived

Difference between revisions of "Developing a MVC Component/Adding verifications"

From Joomla! Documentation

< Archived:Developing a MVC Component
(→‎Verifying the form (server side): Remove incorrect comment and add explanation)
(81 intermediate revisions by 15 users not shown)
Line 1: Line 1:
{{underconstruction}}
+
{{version/tutor|2.5}}
{{future|1.6}}
+
{{Chunk:Developing a Model-View-Controller (MVC) Component for Joomla!2.5 - Contents}}
  
== Articles in this series ==
+
== Introduction ==
* [[Developing a Model-View-Controller (MVC) Component for Joomla!1.6 - Part 01|Developing a Basic Component]]
+
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.
* [[Developing a Model-View-Controller (MVC) Component for Joomla!1.6 - Part 02|Adding a view to the site part]]
 
* [[Developing a Model-View-Controller (MVC) Component for Joomla!1.6 - Part 03|Adding a menu type to the backend part]]
 
* [[Developing a Model-View-Controller (MVC) Component for Joomla!1.6 - Part 04|Adding a model to the site part]]
 
* [[Developing a Model-View-Controller (MVC) Component for Joomla!1.6 - Part 05|Adding a variable request in the menu type]]
 
* [[Developing a Model-View-Controller (MVC) Component for Joomla!1.6 - Part 06|Using the database]]
 
* [[Developing a Model-View-Controller (MVC) Component for Joomla!1.6 - Part 07|Basic backend]]
 
* [[Developing a Model-View-Controller (MVC) Component for Joomla!1.6 - Part 08|Adding language management]]
 
* [[Developing a Model-View-Controller (MVC) Component for Joomla!1.6 - Part 09|Adding backend actions]]
 
* [[Developing a Model-View-Controller (MVC) Component for Joomla!1.6 - Part 10|Adding decorations to the backend]]
 
* [[Developing a Model-View-Controller (MVC) Component for Joomla!1.6 - Part 11|Adding verifications]]
 
* [[Developing a Model-View-Controller (MVC) Component for Joomla!1.6 - Part 12|Adding categories]]
 
* [[Developing a Model-View-Controller (MVC) Component for Joomla!1.6 - Part 13|Adding configuration]]
 
* [[Developing a Model-View-Controller (MVC) Component for Joomla!1.6 - Part 14|Adding ACL]]
 
* [[Developing a Model-View-Controller (MVC) Component for Joomla!1.6 - Part 15|Adding an install/uninstall/update script file]]
 
* [[Developing a Model-View-Controller (MVC) Component for Joomla!1.6 - Part 16|Adding an update server]]
 
  
== Indroduction ==
+
See [[Form validation]] for some more general info on form validation (rules).
This tutorial is part of the [[Developing a Model-View-Controller (MVC) Component for Joomla!1.6]] tutorial. You are encouraged to read the previous parts of the tutorial before reading this.
 
  
== Preventing CSRF attacks ==
+
== Verifying the form (client side) ==
A way to prevent [http://en.wikipedia.org/wiki/Cross-site_request_forgery CSRF attacks] is to use tokens in the forms. Joomla!1.6 provides a function to generate tokens and function to check them.
 
  
In the ''admin/views/helloworldlist/tmpl/default.php'' file put these lines
+
Forms can be verified on the client side using javascript code.
  
<span id="admin/views/helloworldlist/tmpl/default.php">
+
In the ''[[#admin/views/helloworld/tmpl/edit.php|admin/views/helloworld/tmpl/edit.php]]'' file, put these lines
''admin/views/helloworldlist/tmpl/default.php''
 
<source lang="php">
 
<?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">
 
<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>
 
<input type="hidden" name="task" value="" />
 
<input type="hidden" name="boxchecked" value="0" />
 
<?php echo JHtml::_('form.token'); ?>
 
</form>
 
</source>
 
</span>
 
 
 
The ''echo JHtml::_('form.token');'' generates the token.
 
 
 
Rename the ''admin/views/helloworld/tmpl/default.php'' file into ''admin/views/helloworld/tmpl/edit.php'' (because we will use a ''JControllerForm'' inherited class) and put these lines
 
  
 
<span id="admin/views/helloworld/tmpl/edit.php">
 
<span id="admin/views/helloworld/tmpl/edit.php">
Line 60: Line 19:
 
// No direct access
 
// No direct access
 
defined('_JEXEC') or die('Restricted access');
 
defined('_JEXEC') or die('Restricted access');
JHTML::_('behavior.tooltip');
+
JHtml::_('behavior.tooltip');
JHTML::_('behavior.formvalidation');
+
JHtml::_('behavior.formvalidation');
 
?>
 
?>
<form action="<?php echo JRoute::_('index.php?option=com_helloworld'); ?>" method="post" name="adminForm" id="adminForm" class="form-validate">
+
<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="form-validate">
 
<fieldset class="adminform">
 
<fieldset class="adminform">
<legend><?php echo JText::_( 'com_helloworld_HelloWorld_Details' ); ?></legend>
+
<legend><?php echo JText::_( 'COM_HELLOWORLD_HELLOWORLD_DETAILS' ); ?></legend>
<?php foreach($this->form->getFields() as $field): ?>
+
<?php foreach($this->form->getFieldset() as $field): ?>
 
<?php if (!$field->hidden): ?>
 
<?php if (!$field->hidden): ?>
 
<?php echo $field->label; ?>
 
<?php echo $field->label; ?>
 
 
<?php endif; ?>
 
<?php endif; ?>
 
<?php echo $field->input; ?>
 
<?php echo $field->input; ?>
 
 
<?php endforeach; ?>
 
<?php endforeach; ?>
 
</fieldset>
 
</fieldset>
<input type="hidden" name="task" value="helloworld.edit" />
+
<div>
<?php echo JHtml::_('form.token'); ?>
+
<input type="hidden" name="task" value="helloworld.edit" />
 +
<?php echo JHtml::_('form.token'); ?>
 +
</div>
 
</form>
 
</form>
 
</source>
 
</source>
 
</span>
 
</span>
  
Tokens are now generated in the forms. They have to be verified in the controllers.
 
 
In the ''admin/controllers/helloworldlist.php'' file put these lines
 
 
<span id="admin/controllers/helloworldlist.php">
 
''admin/controllers/helloworldlist.php''
 
<source lang="php">
 
<?php
 
// No direct access to this file
 
defined('_JEXEC') or die('Restricted access');
 
// inherit general controller
 
require_once JPATH_COMPONENT . DS .'controller.php';
 
/**
 
* HelloWorldList Controller
 
*/
 
class HelloWorldControllerHelloWorldList extends HelloWorldController
 
{
 
/**
 
* remove record(s)
 
* @return void
 
*/
 
function remove()
 
{
 
JRequest::checkToken() or jexit(JText::_('JInvalid_Token'));
 
$model = $this->getModel('HelloWorldList');
 
if ($model->remove())
 
{
 
$msg = JText::_('com_helloworld_HelloWorldList_Greetings_removed');
 
$type = 'message';
 
}
 
else
 
{
 
$msg = JText::sprintf('com_helloworld_HelloWorldList_One_or_more_greetings_could_not_be_deleted', implode("<br />", $model->getErrors()));
 
$type = 'error';
 
}
 
$this->setRedirect('index.php?option=com_helloworld', $msg, $type);
 
}
 
}
 
</source>
 
</span>
 
 
The ''JRequest::checkToken'' call verifies the generated token.
 
  
For the other controller, there is now in Joomla!1.6 a 'JControllerForm'' class. It is used for managing (editing, saving, ...) item.
+
You may have noted that the html form contained in the ''[[#admin/views/helloworld/tmpl/edit.php|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.
 
 
In the ''admin/controllers/helloworld.php'' file put these lines
 
 
 
<span id="admin/controllers/helloworld.php">
 
''admin/controllers/helloworld.php''
 
<source lang="php">
 
<?php
 
/**
 
* @version    $Id: helloworld.php 28 2009-11-13 14:47:57Z chdemko $
 
* @package    Joomla16.Tutorials
 
* @subpackage Components
 
* @copyright  Copyright (C) 2005 - 2009 Open Source Matters, Inc. All rights reserved.
 
* @author    Christophe Demko
 
* @link      http://joomlacode.org/gf/project/helloworld_1_6/
 
* @license    GNU/GPL
 
*/
 
// No direct access to this file
 
defined('_JEXEC') or die('Restricted access');
 
// import Joomla controllerform library
 
jimport('joomla.application.component.controllerform');
 
/**
 
* HelloWorld Controller
 
*/
 
class HelloWorldControllerHelloWorld extends JControllerForm
 
{
 
function __construct ($config=array())
 
{
 
parent::__construct($config);
 
jimport('joomla.form.formvalidator');
 
JFormValidator::addRulePath(JPATH_COMPONENT . DS . 'models' . DS . 'rules');
 
}
 
protected $_view_list = 'HelloWorldList';
 
}
 
</source>
 
</span>
 
 
 
== Verifying the form (client side) ==
 
Forms can be verified on the client side using javascript code. You may have noted that the html form contained in the ''[[#admin/views/helloworld/default.php|admin/views/helloworld/default.php]]'' file now has the ''form-validate'' class. And that we added a ''JHTML::_('behavior.formvalidation');'' call to tell Joomla!1.6 to use its javascript form validation.
 
  
 
Modify the ''admin/models/forms/helloworld.xml'' file to indicate that the ''greeting'' field has to be verified:
 
Modify the ''admin/models/forms/helloworld.xml'' file to indicate that the ''greeting'' field has to be verified:
Line 168: Line 48:
 
<span id="admin/models/forms/helloworld.xml">
 
<span id="admin/models/forms/helloworld.xml">
 
<source lang="xml">
 
<source lang="xml">
 +
 
<?xml version="1.0" encoding="utf-8"?>
 
<?xml version="1.0" encoding="utf-8"?>
<form>
+
<form
<fields>
+
addrulepath="/administrator/components/com_helloworld/models/rules"
 +
>
 +
<fieldset>
 
<field
 
<field
id="id"
 
 
name="id"
 
name="id"
 
type="hidden"
 
type="hidden"
 
/>
 
/>
 
<field
 
<field
id="greeting"
 
 
name="greeting"
 
name="greeting"
 
type="text"
 
type="text"
 +
label="COM_HELLOWORLD_HELLOWORLD_GREETING_LABEL"
 +
description="COM_HELLOWORLD_HELLOWORLD_GREETING_DESC"
 
size="40"
 
size="40"
 
class="inputbox validate-greeting"
 
class="inputbox validate-greeting"
Line 185: Line 68:
 
required="true"
 
required="true"
 
default=""
 
default=""
label="com_helloworld_HelloWorld_Greeting"
 
description="com_helloworld_HelloWorld_Greeting_Desc"
 
 
/>
 
/>
</fields>
+
</fieldset>
</form></source>
+
</form>
 +
</source>
 
</span>
 
</span>
  
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 an handler of the form validator framework of Joomla
+
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
 
With your favorite file manager and editor put a file ''admin/models/forms/helloworld.js'' containing
Line 209: Line 91:
 
</span>
 
</span>
  
It adds an handler to the form validator of Joomla for fields having the ''"validate-greeting"'' css class. Each time a field the ''greeting'' field is modified, the handler will be executed to verify its validaty (no digits).
+
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.
 
The final step is to verify the form when the save button is clicked.
Line 218: Line 100:
 
''admin/views/helloworld/submitbutton.js''
 
''admin/views/helloworld/submitbutton.js''
 
<source lang="javascript">
 
<source lang="javascript">
function submitbutton(task)
+
Joomla.submitbutton = function(task)
 
{
 
{
 
if (task == '')
 
if (task == '')
Line 227: Line 109:
 
{
 
{
 
var isValid=true;
 
var isValid=true;
if (task != 'helloworld.cancel' && task != 'helloworld.close')
+
var action = task.split('.');
 +
if (action[1] != 'cancel' && action[1] != 'close')
 
{
 
{
 
var forms = $$('form.form-validate');
 
var forms = $$('form.form-validate');
Line 242: Line 125:
 
if (isValid)
 
if (isValid)
 
{
 
{
submitform(task);
+
Joomla.submitform(task);
 
return true;
 
return true;
 
}
 
}
 
else
 
else
 
{
 
{
alert(Joomla.JText._('com_helloworld_HelloWorld_Error_Some_Values_Are_Unacceptable','Some values are unacceptable'));
+
alert(Joomla.JText._('COM_HELLOWORLD_HELLOWORLD_ERROR_UNACCEPTABLE',
 +
                    'Some values are unacceptable'));
 
return false;
 
return false;
 
}
 
}
Line 255: Line 139:
 
</span>
 
</span>
  
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!1.6 framework.
+
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:
 
The ''HelloWorldViewHelloWorld'' view class has to be modified to use these javascript files:
Line 265: Line 149:
 
// No direct access to this file
 
// No direct access to this file
 
defined('_JEXEC') or die('Restricted access');
 
defined('_JEXEC') or die('Restricted access');
 +
 
// import Joomla view library
 
// import Joomla view library
 
jimport('joomla.application.component.view');
 
jimport('joomla.application.component.view');
 +
 
/**
 
/**
 
  * HelloWorld View
 
  * HelloWorld View
Line 272: Line 158:
 
class HelloWorldViewHelloWorld extends JView
 
class HelloWorldViewHelloWorld extends JView
 
{
 
{
/**
 
* View form
 
*
 
* @var form
 
*/
 
protected $form = null;
 
/**
 
* View script
 
*/
 
protected $script = null;
 
 
/**
 
/**
 
* display method of Hello view
 
* display method of Hello view
Line 288: Line 164:
 
public function display($tpl = null)  
 
public function display($tpl = null)  
 
{
 
{
// get the Form
 
$form = & $this->get('Form');
 
 
// get the Data
 
// get the Data
$data = & $this->get('Data');
+
$form = $this->get('Form');
// get the script
+
$item = $this->get('Item');
$script = & $this->get('Script');
+
$script = $this->get('Script');
// Check for errors
+
 
 +
// Check for errors.
 
if (count($errors = $this->get('Errors')))  
 
if (count($errors = $this->get('Errors')))  
 
{
 
{
JError::raiseError(500, implode("<br />", $errors));
+
JError::raiseError(500, implode('<br />', $errors));
return;
+
return false;
 
}
 
}
// Bind the Data
+
// Assign the Data
$form->bind($data);
 
// Assign the form
 
 
$this->form = $form;
 
$this->form = $form;
// Assign the script
+
$this->item = $item;
 
$this->script = $script;
 
$this->script = $script;
 +
 
// Set the toolbar
 
// Set the toolbar
$this->_setToolBar();
+
$this->addToolBar();
 +
 
 
// Display the template
 
// Display the template
 
parent::display($tpl);
 
parent::display($tpl);
 +
 
// Set the document
 
// Set the document
$this->_setDocument();
+
$this->setDocument();
 
}
 
}
 +
 
/**
 
/**
 
* Setting the toolbar
 
* Setting the toolbar
 
*/
 
*/
protected function _setToolBar()  
+
protected function addToolBar()  
 
{
 
{
JRequest::setVar('hidemainmenu', 1);
+
$input = JFactory::getApplication()->input;
$isNew = ($this->form->getValue('id') < 1);
+
$input->set('hidemainmenu', true);
JToolBarHelper::title(JText::_('com_helloworld_Manager') . ': <small><small>[ ' . ($isNew ? JText::_('JToolBar_New') : JText::_('JToolBar_Edit')) . ' ]</small></small>', 'helloworld');
+
$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::save('helloworld.save');
JToolBarHelper::cancel('helloworld.cancel', $isNew ? 'JToolBar_Cancel' : 'JToolBar_Close');
+
JToolBarHelper::cancel('helloworld.cancel', $isNew ? 'JTOOLBAR_CANCEL' : 'JTOOLBAR_CLOSE');
 
}
 
}
 
/**
 
/**
Line 329: Line 208:
 
* @return void
 
* @return void
 
*/
 
*/
protected function _setDocument()  
+
protected function setDocument()  
 
{
 
{
$isNew = ($this->form->getValue('id') < 1);
+
$isNew = ($this->item->id < 1);
$document = &JFactory::getDocument();
+
$document = JFactory::getDocument();
$document->setTitle(JText::_('com_helloworld_Administration') . ' - ' . ($isNew ? JText::_('com_helloworld_HelloWorld_Creating') : JText::_('com_helloworld_HelloWorld_Editing')));
+
$document->setTitle($isNew ? JText::_('COM_HELLOWORLD_HELLOWORLD_CREATING')
 +
                          : JText::_('COM_HELLOWORLD_HELLOWORLD_EDITING'));
 
$document->addScript(JURI::root() . $this->script);
 
$document->addScript(JURI::root() . $this->script);
$document->addScript(JURI::root() . 'administrator/components/com_helloworld/views/helloworld/submitbutton.js');
+
$document->addScript(JURI::root() . "/administrator/components/com_helloworld"
JText::script('com_helloworld_HelloWorld_Error_Some_Values_Are_Unacceptable');
+
                                  . "/views/helloworld/submitbutton.js");
 +
JText::script('COM_HELLOWORLD_HELLOWORLD_ERROR_UNACCEPTABLE');
 
}
 
}
 
}
 
}
Line 345: Line 226:
 
* verifies if the model has no error;
 
* verifies if the model has no error;
 
* adds two javascript files;
 
* adds two javascript files;
* injects javascript translation using the Joomla!1.6 ''JText::script'' function.
+
* injects javascript translation using the Joomla ''JText::script'' function.
  
 
The final step is to implement a ''getScript'' function in the ''HelloWorldModelHelloWorld'' model:
 
The final step is to implement a ''getScript'' function in the ''HelloWorldModelHelloWorld'' model:
Line 353: Line 234:
 
<source lang="php">
 
<source lang="php">
 
<?php
 
<?php
/**
 
* @version    $Id: helloworld.php 27 2009-11-13 09:47:50Z chdemko $
 
* @package    Joomla16.Tutorials
 
* @subpackage Components
 
* @copyright  Copyright (C) 2005 - 2009 Open Source Matters, Inc. All rights reserved.
 
* @author    Christophe Demko
 
* @link      http://joomlacode.org/gf/project/helloworld_1_6/
 
* @license    GNU/GPL
 
*/
 
 
// No direct access to this file
 
// No direct access to this file
 
defined('_JEXEC') or die('Restricted access');
 
defined('_JEXEC') or die('Restricted access');
 +
 
// import Joomla modelform library
 
// import Joomla modelform library
jimport('joomla.application.component.modelform');
+
jimport('joomla.application.component.modeladmin');
 +
 
 
/**
 
/**
 
  * HelloWorld Model
 
  * HelloWorld Model
 
  */
 
  */
class HelloWorldModelHelloWorld extends JModelForm
+
class HelloWorldModelHelloWorld extends JModelAdmin
 
{
 
{
 
/**
 
/**
* @var array data
+
* 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
 
*/
 
*/
protected $data = null;
+
public function getTable($type = 'HelloWorld', $prefix = 'HelloWorldTable', $config = array())  
/**
 
* Method to auto-populate the model state.
 
*/
 
protected function _populateState()
 
 
{
 
{
$app = JFactory::getApplication('administrator');
+
return JTable::getInstance($type, $prefix, $config);
 
 
// Load the User state.
 
if (!($pk = (int) $app->getUserState('com_helloworld.edit.helloworld.id'))) {
 
$pk = (int) JRequest::getInt('id');
 
}
 
$this->setState('helloworld.id', $pk);
 
 
}
 
}
 
/**
 
/**
* Method to get the data.
+
* Method to get the record form.
 
*
 
*
* @access public
+
* @param array $data Data for the form.
* @return array of string
+
* @param boolean $loadData True if the form is to load its own data (default case), false if not.
* @since 1.0
+
* @return mixed A JForm object on success, false on failure
 +
* @since 2.5
 
*/
 
*/
public function &getData()  
+
public function getForm($data = array(), $loadData = true)  
 
{
 
{
if (empty($this->data))  
+
// Get the form.
 +
$form = $this->loadForm('com_helloworld.helloworld', 'helloworld',
 +
                        array('control' => 'jform', 'load_data' => $loadData));
 +
if (empty($form))  
 
{
 
{
$app = & JFactory::getApplication();
+
return false;
$data = & JRequest::getVar('jform');
 
if (empty($data))
 
{
 
$selected = $this->getState('helloworld.id');
 
$query = new JQuery;
 
// Select all fields from the hello table.
 
$query->select('*');
 
$query->from('`#__helloworld`');
 
$query->where('id = ' . (int)$selected);
 
$this->_db->setQuery((string)$query);
 
$data = & $this->_db->loadAssoc();
 
}
 
if (empty($data))
 
{
 
// Check the session for previously entered form data.
 
$data = $app->getUserState('com_helloworld.edit.helloworld.data', array());
 
unset($data['id']);
 
}
 
$app->setUserState('com_helloworld.edit.helloworld.data', $data);
 
$this->data = $data;
 
 
}
 
}
return $this->data;
 
}
 
/**
 
* Method to get the HelloWorld form.
 
*
 
* @access public
 
* @return mixed JForm object on success, false on failure.
 
* @since 1.0
 
*/
 
public function &getForm()
 
{
 
$form = & parent::getForm('helloworld', 'form', array('array' => 'jform') , false);
 
 
return $form;
 
return $form;
 
}
 
}
 
/**
 
/**
* Method to get the javascript attached to the form
+
* Method to get the script that have to be included on the form
 
*
 
*
* @return string URL to the script.
+
* @return string Script files
 
*/
 
*/
function getScript()  
+
public function getScript()  
 
{
 
{
 
return 'administrator/components/com_helloworld/models/forms/helloworld.js';
 
return 'administrator/components/com_helloworld/models/forms/helloworld.js';
 
}
 
}
 
/**
 
/**
* Method to save a record
+
* Method to get the data that should be injected in the form.
 
*
 
*
* @param array $data array of data
+
* @return mixed The data for the form.
* @access public
+
* @since 2.5
* @return boolean True on success
 
 
*/
 
*/
function save($data)  
+
protected function loadFormData()  
 
{
 
{
// Database processing
+
// Check the session for previously entered form data.
$row = & $this->getTable();
+
$data = JFactory::getApplication()->getUserState('com_helloworld.edit.helloworld.data', array());
// Bind the form fields to the hello table
+
if (empty($data))  
if (!$row->save($data))  
 
 
{
 
{
$this->setError($row->getErrorMsg());
+
$data = $this->getItem();
return false;
 
 
}
 
}
return true;
+
return $data;
 
}
 
}
 
}
 
}
Line 468: Line 307:
  
 
== Verifying the form (server side) ==
 
== Verifying the form (server side) ==
Verifying the form on the server side is done by inheritance of ''JControllerForm'' class. We have specified in the ''[[#admin/models/forms/helloworld.xml|admin/models/forms/helloworld.xml]]'' file that the validate server function will used a ''greeting.php'' file. With the ''JFormValidator::addRulePath(JPATH_COMPONENT . DS . 'models' . DS . 'rules');'' line in the ''[[#admin/controllers/helloworld.php|admin/controllers/helloworld.php]], we specify that this file can be found by the form validator in the ''rules'' folder.
+
Verifying the form on the server side is done by inheritance of ''JControllerForm'' class. We have specified in the ''[[#admin/models/forms/helloworld.xml|admin/models/forms/helloworld.xml]]'' file that the validate server function will use a ''greeting.php'' file.
  
 
With your favorite file manager and editor, put a ''admin/models/rules/greeting.php'' file containing:
 
With your favorite file manager and editor, put a ''admin/models/rules/greeting.php'' file containing:
Line 478: Line 317:
 
// No direct access to this file
 
// No direct access to this file
 
defined('_JEXEC') or die('Restricted access');
 
defined('_JEXEC') or die('Restricted access');
 +
 
// import Joomla formrule library
 
// import Joomla formrule library
 
jimport('joomla.form.formrule');
 
jimport('joomla.form.formrule');
 +
 
/**
 
/**
 
  * Form Rule class for the Joomla Framework.
 
  * Form Rule class for the Joomla Framework.
Line 490: Line 331:
 
* @access protected
 
* @access protected
 
* @var string
 
* @var string
* @since 1.6
+
* @since 2.5
 
*/
 
*/
protected $_regex = '^[^0-9]+$';
+
protected $regex = '^[^0-9]+$';
 
}
 
}
 
</source>
 
</source>
 
</span>
 
</span>
 +
 +
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.
  
 
== Packaging the component ==
 
== Packaging the component ==
Line 501: Line 344:
 
Content of your code directory
 
Content of your code directory
 
* ''[[#helloworld.xml|helloworld.xml]]''
 
* ''[[#helloworld.xml|helloworld.xml]]''
* ''[[Developing_a_Model-View-Controller_(MVC)_Component_for_Joomla!1.6_-_Part_01#index.html|site/index.html]]''
+
* ''[[Developing_a_Model-View-Controller_(MVC)_Component_for_Joomla!2.5_-_Part_01#index.html|site/index.html]]''
* ''[[Developing_a_Model-View-Controller_(MVC)_Component_for_Joomla!1.6_-_Part_02#site/helloworld.php|site/helloworld.php]]''
+
* ''[[Developing_a_Model-View-Controller_(MVC)_Component_for_Joomla!2.5_-_Part_02#site/helloworld.php|site/helloworld.php]]''
* ''[[Developing_a_Model-View-Controller_(MVC)_Component_for_Joomla!1.6_-_Part_01#index.html|site/views/index.html]]''
+
* ''[[Developing_a_Model-View-Controller_(MVC)_Component_for_Joomla!2.5_-_Part_02#site/controller.php|site/controller.php]]''
* ''[[Developing_a_Model-View-Controller_(MVC)_Component_for_Joomla!1.6_-_Part_01#index.html|site/views/helloworld/index.html]]''
+
* ''[[Developing_a_Model-View-Controller_(MVC)_Component_for_Joomla!2.5_-_Part_01#index.html|site/views/index.html]]''
* ''[[Developing_a_Model-View-Controller_(MVC)_Component_for_Joomla!1.6_-_Part_04#site/views/helloworld/view.html.php|site/views/helloworld/view.html.php]]''
+
* ''[[Developing_a_Model-View-Controller_(MVC)_Component_for_Joomla!2.5_-_Part_01#index.html|site/views/helloworld/index.html]]''
* ''[[Developing_a_Model-View-Controller_(MVC)_Component_for_Joomla!1.6_-_Part_01#index.html|site/views/helloworld/tmpl/index.html]]''
+
* ''[[Developing_a_Model-View-Controller_(MVC)_Component_for_Joomla!2.5_-_Part_04#site/views/helloworld/view.html.php|site/views/helloworld/view.html.php]]''
* ''[[Developing_a_Model-View-Controller_(MVC)_Component_for_Joomla!1.6_-_Part_06#site/views/helloworld/tmpl/default.xml|site/views/helloworld/tmpl/default.xml]]''
+
* ''[[Developing_a_Model-View-Controller_(MVC)_Component_for_Joomla!2.5_-_Part_01#index.html|site/views/helloworld/tmpl/index.html]]''
* ''[[Developing_a_Model-View-Controller_(MVC)_Component_for_Joomla!1.6_-_Part_01#index.html|site/models/index.html]]''
+
* ''[[Developing_a_Model-View-Controller_(MVC)_Component_for_Joomla!2.5_-_Part_06#site/views/helloworld/tmpl/default.xml|site/views/helloworld/tmpl/default.xml]]''
* ''[[Developing_a_Model-View-Controller_(MVC)_Component_for_Joomla!1.6_-_Part_06#site/models/helloworld.php|site/models/helloworld.php]]''
+
* ''[[Developing_a_Model-View-Controller_(MVC)_Component_for_Joomla!2.5_-_Part_02#site/views/helloworld/tmpl/default.php|site/views/helloworld/tmpl/default.php]]''
* ''[[Developing_a_Model-View-Controller_(MVC)_Component_for_Joomla!1.6_-_Part_02#site/views/helloworld/tmpl/default.php|site/views/helloworld/tmpl/default.php]]''
+
* ''[[Developing_a_Model-View-Controller_(MVC)_Component_for_Joomla!2.5_-_Part_01#index.html|site/models/index.html]]''
* ''[[Developing_a_Model-View-Controller_(MVC)_Component_for_Joomla!1.6_-_Part_01#index.html|site/language/index.html]]''
+
* ''[[Developing_a_Model-View-Controller_(MVC)_Component_for_Joomla!2.5_-_Part_06#site/models/helloworld.php|site/models/helloworld.php]]''
* ''[[Developing_a_Model-View-Controller_(MVC)_Component_for_Joomla!1.6_-_Part_01#index.html|site/language/en-GB/index.html]]''
+
* ''[[Developing_a_Model-View-Controller_(MVC)_Component_for_Joomla!2.5_-_Part_01#index.html|site/language/index.html]]''
* ''[[Developing_a_Model-View-Controller_(MVC)_Component_for_Joomla!1.6_-_Part_08#site/language/en-GB/en-GB.com_helloworld.ini|site/language/en-GB/en-GB.com_helloworld.ini]]''
+
* ''[[Developing_a_Model-View-Controller_(MVC)_Component_for_Joomla!2.5_-_Part_01#index.html|site/language/en-GB/index.html]]''
* ''[[Developing_a_Model-View-Controller_(MVC)_Component_for_Joomla!1.6_-_Part_01#index.html|admin/index.html]]''
+
* ''[[Developing_a_Model-View-Controller_(MVC)_Component_for_Joomla!2.5_-_Part_08#site/language/en-GB/en-GB.com_helloworld.ini|site/language/en-GB/en-GB.com_helloworld.ini]]''
* ''[[Developing_a_Model-View-Controller_(MVC)_Component_for_Joomla!1.6_-_Part_07#admin/helloworld.php|admin/helloworld.php]]''
+
* ''[[Developing_a_Model-View-Controller_(MVC)_Component_for_Joomla!2.5_-_Part_01#index.html|admin/index.html]]''
* ''[[Developing_a_Model-View-Controller_(MVC)_Component_for_Joomla!1.6_-_Part_10#admin/controller.php|admin/controller.php]]''
+
* ''[[Developing_a_Model-View-Controller_(MVC)_Component_for_Joomla!2.5_-_Part_10#admin/helloworld.php|admin/helloworld.php]]''
* ''[[Developing_a_Model-View-Controller_(MVC)_Component_for_Joomla!1.6_-_Part_01#index.html|admin/sql/index.html]]''
+
* ''[[Developing_a_Model-View-Controller_(MVC)_Component_for_Joomla!2.5_-_Part_07#admin/controller.php|admin/controller.php]]''
* ''[[Developing_a_Model-View-Controller_(MVC)_Component_for_Joomla!1.6_-_Part_06#admin/sql/install.mysql.utf8.sql|admin/sql/install.mysql.utf8.sql]]''
+
* ''[[Developing_a_Model-View-Controller_(MVC)_Component_for_Joomla!2.5_-_Part_01#index.html|admin/sql/index.html]]''
* ''[[Developing_a_Model-View-Controller_(MVC)_Component_for_Joomla!1.6_-_Part_06#admin/sql/uninstall.mysql.utf8.sql|admin/sql/uninstall.mysql.utf8.sql]]''
+
* ''[[Developing_a_Model-View-Controller_(MVC)_Component_for_Joomla!2.5_-_Part_06#admin/sql/install.mysql.utf8.sql|admin/sql/install.mysql.utf8.sql]]''
* ''[[Developing_a_Model-View-Controller_(MVC)_Component_for_Joomla!1.6_-_Part_06#admin/sql/update.mysql.utf8.sql|admin/sql/update.mysql.utf8.sql]]''
+
* ''[[Developing_a_Model-View-Controller_(MVC)_Component_for_Joomla!2.5_-_Part_06#admin/sql/uninstall.mysql.utf8.sql|admin/sql/uninstall.mysql.utf8.sql]]''
* ''[[Developing_a_Model-View-Controller_(MVC)_Component_for_Joomla!1.6_-_Part_01#index.html|admin/models/index.html]]''
+
* ''[[Developing_a_Model-View-Controller_(MVC)_Component_for_Joomla!2.5_-_Part_01#index.html|admin/sql/updates/index.html]]''
* ''[[Developing_a_Model-View-Controller_(MVC)_Component_for_Joomla!1.6_-_Part_01#index.html|admin/models/fields/index.html]]''
+
* ''[[Developing_a_Model-View-Controller_(MVC)_Component_for_Joomla!2.5_-_Part_01#index.html|admin/sql/updates/mysql/index.html]]''
* ''[[Developing_a_Model-View-Controller_(MVC)_Component_for_Joomla!1.6_-_Part_06#admin/models/fields/helloworld.php|admin/models/fields/helloworld.php]]''
+
* ''[[Developing_a_Model-View-Controller_(MVC)_Component_for_Joomla!2.5_-_Part_01#admin/sql/updates/mysql/0.0.1.sql|admin/sql/updates/mysql/0.0.1.sql]]''
* ''[[Developing_a_Model-View-Controller_(MVC)_Component_for_Joomla!1.6_-_Part_01#index.html|admin/models/forms/index.html]]''
+
* ''[[Developing_a_Model-View-Controller_(MVC)_Component_for_Joomla!2.5_-_Part_06#admin/sql/install.mysql.utf8.sql|admin/sql/updates/mysql/0.0.6.sql]]''
 +
* ''[[Developing_a_Model-View-Controller_(MVC)_Component_for_Joomla!2.5_-_Part_01#index.html|admin/models/index.html]]''
 +
* ''[[Developing_a_Model-View-Controller_(MVC)_Component_for_Joomla!2.5_-_Part_01#index.html|admin/models/fields/index.html]]''
 +
* ''[[Developing_a_Model-View-Controller_(MVC)_Component_for_Joomla!2.5_-_Part_06#admin/models/fields/helloworld.php|admin/models/fields/helloworld.php]]''
 +
* ''[[Developing_a_Model-View-Controller_(MVC)_Component_for_Joomla!2.5_-_Part_01#index.html|admin/models/forms/index.html]]''
 
* ''[[#admin/models/forms/helloworld.xml|admin/models/forms/helloworld.xml]]''
 
* ''[[#admin/models/forms/helloworld.xml|admin/models/forms/helloworld.xml]]''
 
* ''[[#admin/models/forms/helloworld.js|admin/models/forms/helloworld.js]]''
 
* ''[[#admin/models/forms/helloworld.js|admin/models/forms/helloworld.js]]''
* ''[[Developing_a_Model-View-Controller_(MVC)_Component_for_Joomla!1.6_-_Part_01#index.html|admin/models/rules/index.html]]''
+
* ''[[Developing_a_Model-View-Controller_(MVC)_Component_for_Joomla!2.5_-_Part_01#index.html|admin/models/rules/index.html]]''
 
* ''[[#admin/models/rules/greeting.php|admin/models/rules/greeting.php]]''
 
* ''[[#admin/models/rules/greeting.php|admin/models/rules/greeting.php]]''
 
* ''[[#admin/models/helloworld.php|admin/models/helloworld.php]]''
 
* ''[[#admin/models/helloworld.php|admin/models/helloworld.php]]''
* ''[[Developing_a_Model-View-Controller_(MVC)_Component_for_Joomla!1.6_-_Part_09#admin/models/helloworldlist.php|admin/models/helloworldlist.php]]''
+
* ''[[Developing_a_Model-View-Controller_(MVC)_Component_for_Joomla!2.5_-_Part_09#admin/models/helloworlds.php|admin/models/helloworlds.php]]''
* ''[[Developing_a_Model-View-Controller_(MVC)_Component_for_Joomla!1.6_-_Part_01#index.html|admin/views/index.html]]''
+
* ''[[Developing_a_Model-View-Controller_(MVC)_Component_for_Joomla!2.5_-_Part_01#index.html|admin/views/index.html]]''
* ''[[Developing_a_Model-View-Controller_(MVC)_Component_for_Joomla!1.6_-_Part_01#index.html|admin/views/helloworldlist/index.html]]''
+
* ''[[Developing_a_Model-View-Controller_(MVC)_Component_for_Joomla!2.5_-_Part_01#index.html|admin/views/helloworlds/index.html]]''
* ''[[Developing_a_Model-View-Controller_(MVC)_Component_for_Joomla!1.6_-_Part_10#admin/views/helloworldlist/view.html.php|admin/views/helloworldlist/view.html.php]]''
+
* ''[[Developing_a_Model-View-Controller_(MVC)_Component_for_Joomla!2.5_-_Part_10#admin/views/helloworlds/view.html.php|admin/views/helloworlds/view.html.php]]''
* ''[[Developing_a_Model-View-Controller_(MVC)_Component_for_Joomla!1.6_-_Part_01#index.html|admin/views/helloworldlist/tmpl/index.html]]''
+
* ''[[Developing_a_Model-View-Controller_(MVC)_Component_for_Joomla!2.5_-_Part_01#index.html|admin/views/helloworlds/tmpl/index.html]]''
* ''[[#admin/views/helloworldlist/tmpl/default.php|admin/views/helloworldlist/tmpl/default.php]]''
+
* ''[[Developing_a_Model-View-Controller_(MVC)_Component_for_Joomla!2.5_-_Part_09#admin/views/helloworlds/tmpl/default.php|admin/views/helloworlds/tmpl/default.php]]''
* ''[[Developing_a_Model-View-Controller_(MVC)_Component_for_Joomla!1.6_-_Part_07#admin/views/helloworldlist/tmpl/default_head.php|admin/views/helloworldlist/tmpl/default_head.php]]''
+
* ''[[Developing_a_Model-View-Controller_(MVC)_Component_for_Joomla!2.5_-_Part_07#admin/views/helloworlds/tmpl/default_head.php|admin/views/helloworlds/tmpl/default_head.php]]''
* ''[[Developing_a_Model-View-Controller_(MVC)_Component_for_Joomla!1.6_-_Part_07#admin/views/helloworldlist/tmpl/default_body.php|admin/views/helloworldlist/tmpl/default_body.php]]''
+
* ''[[Developing_a_Model-View-Controller_(MVC)_Component_for_Joomla!2.5_-_Part_07#admin/views/helloworlds/tmpl/default_body.php|admin/views/helloworlds/tmpl/default_body.php]]''
* ''[[Developing_a_Model-View-Controller_(MVC)_Component_for_Joomla!1.6_-_Part_07#admin/views/helloworldlist/tmpl/default_foot.php|admin/views/helloworldlist/tmpl/default_foot.php]]''
+
* ''[[Developing_a_Model-View-Controller_(MVC)_Component_for_Joomla!2.5_-_Part_07#admin/views/helloworlds/tmpl/default_foot.php|admin/views/helloworlds/tmpl/default_foot.php]]''
* ''[[Developing_a_Model-View-Controller_(MVC)_Component_for_Joomla!1.6_-_Part_01#index.html|admin/views/helloworldlist/index.html]]''
+
* ''[[Developing_a_Model-View-Controller_(MVC)_Component_for_Joomla!2.5_-_Part_01#index.html|admin/views/helloworld/index.html]]''
 
* ''[[#admin/views/helloworld/view.html.php|admin/views/helloworld/view.html.php]]''
 
* ''[[#admin/views/helloworld/view.html.php|admin/views/helloworld/view.html.php]]''
 
* ''[[#admin/views/helloworld/submitbutton.js|admin/views/helloworld/submitbutton.js]]''
 
* ''[[#admin/views/helloworld/submitbutton.js|admin/views/helloworld/submitbutton.js]]''
* ''[[Developing_a_Model-View-Controller_(MVC)_Component_for_Joomla!1.6_-_Part_01#index.html|admin/views/helloworld/tmpl/index.html]]''
+
* ''[[Developing_a_Model-View-Controller_(MVC)_Component_for_Joomla!2.5_-_Part_01#index.html|admin/views/helloworld/tmpl/index.html]]''
 
* ''[[#admin/views/helloworld/tmpl/edit.php|admin/views/helloworld/tmpl/edit.php]]''
 
* ''[[#admin/views/helloworld/tmpl/edit.php|admin/views/helloworld/tmpl/edit.php]]''
* ''[[Developing_a_Model-View-Controller_(MVC)_Component_for_Joomla!1.6_-_Part_01#index.html|admin/tables/index.html]]''
+
* ''[[Developing_a_Model-View-Controller_(MVC)_Component_for_Joomla!2.5_-_Part_01#index.html|admin/tables/index.html]]''
* ''[[Developing_a_Model-View-Controller_(MVC)_Component_for_Joomla!1.6_-_Part_06#admin/tables/helloworld.php|admin/tables/helloworld.php]]''
+
* ''[[Developing_a_Model-View-Controller_(MVC)_Component_for_Joomla!2.5_-_Part_06#admin/tables/helloworld.php|admin/tables/helloworld.php]]''
* ''[[Developing_a_Model-View-Controller_(MVC)_Component_for_Joomla!1.6_-_Part_10#admin/language/en-GB/en-GB.com_helloworld.ini|admin/language/en-GB/en-GB.com_helloworld.ini]]''
+
* ''[[Developing_a_Model-View-Controller_(MVC)_Component_for_Joomla!2.5_-_Part_10#admin/language/en-GB/en-GB.com_helloworld.ini|admin/language/en-GB/en-GB.com_helloworld.ini]]''
* ''[[Developing_a_Model-View-Controller_(MVC)_Component_for_Joomla!1.6_-_Part_08#admin/language/en-GB/en-GB.com_helloworld.menu.ini|admin/language/en-GB/en-GB.com_helloworld.menu.ini]]''
+
* ''[[Developing_a_Model-View-Controller_(MVC)_Component_for_Joomla!2.5_-_Part_08#admin/language/en-GB/en-GB.com_helloworld.sys.ini|admin/language/en-GB/en-GB.com_helloworld.sys.ini]]''
* ''[[Developing_a_Model-View-Controller_(MVC)_Component_for_Joomla!1.6_-_Part_01#index.html|admin/controllers/index.html]]''
+
* ''[[Developing_a_Model-View-Controller_(MVC)_Component_for_Joomla!2.5_-_Part_01#index.html|admin/controllers/index.html]]''
 
* ''[[#admin/controllers/helloworld.php|admin/controllers/helloworld.php]]''
 
* ''[[#admin/controllers/helloworld.php|admin/controllers/helloworld.php]]''
* ''[[#admin/controllers/helloworldlist.php|admin/controllers/helloworldlist.php]]''
+
* ''[[#admin/controllers/helloworlds.php|admin/controllers/helloworlds.php]]''
* ''[[Developing_a_Model-View-Controller_(MVC)_Component_for_Joomla!1.6_-_Part_08#language/en-GB/en-GB.ini|language/en-GB/en-GB.ini]]''
+
* ''[[Developing_a_Model-View-Controller_(MVC)_Component_for_Joomla!2.5_-_Part_08#language/en-GB/en-GB.ini|language/en-GB/en-GB.ini]]''
* ''[[Developing_a_Model-View-Controller_(MVC)_Component_for_Joomla!1.6_-_Part_01#index.html|media/index.html]]''
+
* ''[[Developing_a_Model-View-Controller_(MVC)_Component_for_Joomla!2.5_-_Part_01#index.html|media/index.html]]''
* ''[[Developing_a_Model-View-Controller_(MVC)_Component_for_Joomla!1.6_-_Part_01#index.html|media/images/index.html]]''
+
* ''[[Developing_a_Model-View-Controller_(MVC)_Component_for_Joomla!2.5_-_Part_01#index.html|media/images/index.html]]''
 
* ''media/images/tux-16x16.png''
 
* ''media/images/tux-16x16.png''
 
* ''media/images/tux-48x48.png''
 
* ''media/images/tux-48x48.png''
  
Create a compressed file of this directory or directly download the [http://joomlacode.org/gf/download/frsrelease/11394/46017/com_helloworld-1.6-part08.zip 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.
+
Create a compressed file of this directory or directly download the [http://joomlacode.org/gf/download/frsrelease/11394/58409/com_helloworld-1.6-part11.zip 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.
  
 
<span id="helloworld.xml">
 
<span id="helloworld.xml">
Line 563: Line 410:
 
<source lang="xml">
 
<source lang="xml">
 
<?xml version="1.0" encoding="utf-8"?>
 
<?xml version="1.0" encoding="utf-8"?>
<extension type="component" version="1.6.0" method="upgrade">
+
<extension type="component" version="2.5.0" method="upgrade">
<name>Hello World!</name>
+
 
 +
<name>COM_HELLOWORLD</name>
 +
<!-- The following elements are optional and free of formatting constraints -->
 
<creationDate>November 2009</creationDate>
 
<creationDate>November 2009</creationDate>
 
<author>John Doe</author>
 
<author>John Doe</author>
Line 571: Line 420:
 
<copyright>Copyright Info</copyright>
 
<copyright>Copyright Info</copyright>
 
<license>License Info</license>
 
<license>License Info</license>
 +
<!--  The version string is recorded in the components table -->
 
<version>0.0.11</version>
 
<version>0.0.11</version>
<description>com_helloworld_Description</description>
+
<!-- The description is optional and defaults to the name -->
 +
<description>COM_HELLOWORLD_DESCRIPTION</description>
  
 
<install> <!-- Runs on install -->
 
<install> <!-- Runs on install -->
Line 584: Line 435:
 
</sql>
 
</sql>
 
</uninstall>
 
</uninstall>
<update> <!-- Runs on update -->
+
<update> <!-- Runs on update; New in 2.5 -->
<sql>
+
<schemas>
<file driver="mysql" charset="utf8">sql/update.mysql.utf8.sql</file>
+
<schemapath type="mysql">sql/updates/mysql</schemapath>
</sql>
+
</schemas>
 
</update>
 
</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">
 
<files folder="site">
 
<filename>index.html</filename>
 
<filename>index.html</filename>
Line 603: Line 458:
 
<folder>images</folder>
 
<folder>images</folder>
 
</media>
 
</media>
+
 
 
<administration>
 
<administration>
<menu img="../media/com_helloworld/images/tux-16x16.png">Hello World!</menu>
+
<!-- Administration Menu Section -->
 +
<menu img="../media/com_helloworld/images/tux-16x16.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">
 
<files folder="admin">
 +
<!-- Admin Main File Copy Section -->
 
<filename>index.html</filename>
 
<filename>index.html</filename>
 
<filename>helloworld.php</filename>
 
<filename>helloworld.php</filename>
 
<filename>controller.php</filename>
 
<filename>controller.php</filename>
 +
<!-- SQL files section -->
 
<folder>sql</folder>
 
<folder>sql</folder>
 +
<!-- tables files section -->
 
<folder>tables</folder>
 
<folder>tables</folder>
 +
<!-- models files section -->
 
<folder>models</folder>
 
<folder>models</folder>
 +
<!-- views files section -->
 
<folder>views</folder>
 
<folder>views</folder>
 +
<!-- controllers files section -->
 
<folder>controllers</folder>
 
<folder>controllers</folder>
</files>
+
</files>
 +
 
 
<languages folder="admin">
 
<languages folder="admin">
 
<language tag="en-GB">language/en-GB/en-GB.com_helloworld.ini</language>
 
<language tag="en-GB">language/en-GB/en-GB.com_helloworld.ini</language>
<language tag="en-GB">language/en-GB/en-GB.com_helloworld.menu.ini</language>
+
<language tag="en-GB">language/en-GB/en-GB.com_helloworld.sys.ini</language>
 
</languages>
 
</languages>
 
</administration>
 
</administration>
 +
 
</extension>
 
</extension>
 
</source>
 
</source>
 
</span>
 
</span>
 +
 +
== Navigate ==
 +
[[Developing a Model-View-Controller (MVC) Component for Joomla!2.5 - Part 10|Prev: Adding decorations to the backend]]
 +
[[Developing a Model-View-Controller (MVC) Component for Joomla!2.5 - Part 12|Next: Adding categories]]
  
 
== Contributors ==
 
== Contributors ==
 
*[[User:cdemko|Christophe Demko]]
 
*[[User:cdemko|Christophe Demko]]
 +
*[[User:oaksu|Ozgur Aksu]]
  
 
[[Category:Development]]
 
[[Category:Development]]
[[category:Joomla! 1.6]]
+
[[Category:Joomla! 1.6]]
[[category:Manual]]
+
[[Category:Joomla! 1.7]]
 +
[[Category:Joomla! 2.5]]

Revision as of 20:10, 1 December 2013

This page has been archived. This page contains information for an unsupported Joomla! version or is no longer relevant. It exists only as a historical reference, it will not be improved and its content may be incomplete and/or contain broken links.


Introduction[edit]

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).

Verifying the form (client side)[edit]

Forms can be verified on the client side using javascript code.

In the admin/views/helloworld/tmpl/edit.php file, put these lines

admin/views/helloworld/tmpl/edit.php

<?php
// No direct access
defined('_JEXEC') or die('Restricted access');
JHtml::_('behavior.tooltip');
JHtml::_('behavior.formvalidation');
?>
<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="form-validate">
	<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>


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.

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>

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

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.

With your favorite file manager and editor put a file admin/views/helloworld/submitbutton.js containing

admin/views/helloworld/submitbutton.js

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
		{
			alert(Joomla.JText._('COM_HELLOWORLD_HELLOWORLD_ERROR_UNACCEPTABLE',
			                     'Some values are unacceptable'));
			return false;
		}
	}
}

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');

		// Check for errors.
		if (count($errors = $this->get('Errors'))) 
		{
			JError::raiseError(500, implode('<br />', $errors));
			return false;
		}
		// Assign the Data
		$this->form = $form;
		$this->item = $item;
		$this->script = $script;

		// Set the toolbar
		$this->addToolBar();

		// Display the template
		parent::display($tpl);

		// Set the document
		$this->setDocument();
	}

	/**
	 * 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");
		JText::script('COM_HELLOWORLD_HELLOWORLD_ERROR_UNACCEPTABLE');
	}
}

This view now

  • verifies if the model has no error;
  • adds two javascript files;
  • injects javascript translation using the Joomla JText::script function.

The final step is to implement a getScript function in the HelloWorldModelHelloWorld model:

admin/models/helloworld.php

<?php
// No direct access to this file
defined('_JEXEC') or die('Restricted access');

// import Joomla modelform library
jimport('joomla.application.component.modeladmin');

/**
 * HelloWorld Model
 */
class HelloWorldModelHelloWorld extends JModelAdmin
{
	/**
	 * 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);
	}
	/**
	 * Method to get the record form.
	 *
	 * @param	array	$data		Data for the form.
	 * @param	boolean	$loadData	True if the form is to load its own data (default case), false if not.
	 * @return	mixed	A JForm object on success, false on failure
	 * @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 script that have to be included on the form
	 *
	 * @return string	Script files
	 */
	public function getScript() 
	{
		return 'administrator/components/com_helloworld/models/forms/helloworld.js';
	}
	/**
	 * 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;
	}
}

Verifying the form (server side)[edit]

Verifying the form on the server side is done by inheritance of JControllerForm class. We have specified in the admin/models/forms/helloworld.xml file that the validate server function will use a greeting.php file.

With your favorite file manager and editor, put a admin/models/rules/greeting.php file containing:

admin/models/rules/greeting.php

<?php
// No direct access to this file
defined('_JEXEC') or die('Restricted access');

// import Joomla formrule library
jimport('joomla.form.formrule');

/**
 * Form Rule class for the Joomla Framework.
 */
class JFormRuleGreeting extends JFormRule
{
	/**
	 * The regular expression.
	 *
	 * @access	protected
	 * @var		string
	 * @since	2.5
	 */
	protected $regex = '^[^0-9]+$';
}

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.

Packaging the component[edit]

Content of your code directory

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>john.doe@example.org</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>
			<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>
		<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/tux-16x16.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>

		<languages folder="admin">
			<language tag="en-GB">language/en-GB/en-GB.com_helloworld.ini</language>
			<language tag="en-GB">language/en-GB/en-GB.com_helloworld.sys.ini</language>
		</languages>
	</administration>

</extension>

Navigate[edit]

Prev: Adding decorations to the backend Next: Adding categories

Contributors[edit]