Archived

Developing a MVC Component/Example of a frontend update function

From Joomla! Documentation

< Archived:Developing a MVC Component
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

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.

Stop hand nuvola.svg.png
Warning!

The methods used in this document do not adhere to best practices and do not make optimal use of the flexibility provided by Joomla. More specifically, it is possible and recommended to reuse the model and form created during Adding backend actions for front-end editing. Also, when using JModelForm, one should use the data manipulation methods provided by JModelForm instead of a custom updItem method. This code is not harmful and can be used in components, but could be written in a simpler and more maintainable way. If you are an expert developer, please consider editing this page to use the capabilities mentioned.

Copyedit.png
This Page Needs Your Help

This page is tagged because it NEEDS TECHNICAL REVIEW. You can help the Joomla! Documentation Wiki by contributing to it.
More pages that need help similar to this one are here. NOTE-If you feel the need is satistified, please remove this notice.

Reason: This article needs to be reviewed by someone who knows what they're doing.



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.

Basic frontend form[edit]

Designing the frontend interface leads us to create a Model-View-Controller triptych similar to the backend in Part 7.

Create the specific controller[edit]

The entry point now gets an instance of an UpdHelloWorld prefixed controller which extends the function of JControllerForm. Let's create a basic controllerform for the site part:

site/controllers/updhelloworld.php

<?php

// No direct access.
defined('_JEXEC') or die;

// Include dependancy of the main controllerform class
jimport('joomla.application.component.controllerform');

class HelloWorldControllerUpdHelloWorld extends JControllerForm
{

	public function getModel($name = '', $prefix = '', $config = array('ignore_request' => true))
	{
		return parent::getModel($name, $prefix, array('ignore_request' => false));
	}

	public function submit()
	{
		// Check for request forgeries.
		JRequest::checkToken() or jexit(JText::_('JINVALID_TOKEN'));

		// Initialise variables.
		$app	= JFactory::getApplication();
		$model	= $this->getModel('updhelloworld');

		// Get the data from the form POST
		$data = JRequest::getVar('jform', array(), 'post', 'array');

        // Now update the loaded data to the database via a function in the model
        $upditem	= $model->updItem($data);

    	// check if ok and display appropriate message.  This can also have a redirect if desired.
        if ($upditem) {
            echo "<h2>Updated Greeting has been saved</h2>";
        } else {
            echo "<h2>Updated Greeting failed to be saved</h2>";
        }

		return true;
	}

}

This controller will display the appropriate message after the form is submitted.

Create the view[edit]

With your favorite file manager and editor, create a file site/views/updhelloworld/view.html.php containing:

site/views/updhelloworld/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 UpdHelloWorld Component
 */
class HelloWorldViewUpdHelloWorld extends JView
{
	// Overwriting JView display method
	function display($tpl = null) 
	{
		$app		= JFactory::getApplication();
		$params		= $app->getParams();
		$dispatcher = JDispatcher::getInstance();

		// Get some data from the models
		$state		= $this->get('State');
		$item		= $this->get('Item');
		$this->form	= $this->get('Form');

		// Check for errors.
		if (count($errors = $this->get('Errors'))) 
		{
			JError::raiseError(500, implode('<br />', $errors));
			return false;
		}
		// Display the view
		parent::display($tpl);
	}
}

In Joomla, views display data using a layout. With your favorite file manager and editor, put a file site/views/updhelloworld/tmpl/default.php containing

site/views/updhelloworld/tmpl/default.php

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

JHtml::_('behavior.keepalive');
JHtml::_('behavior.formvalidation');
JHtml::_('behavior.tooltip');

?>
    <h2>Update the Hello World greeting</h2>

    <form class="form-validate" action="<?php echo JRoute::_('index.php'); ?>" method="post" id="updhelloworld" name="updhelloworld">
		<fieldset>
        	<dl>
          	    <dt><?php echo $this->form->getLabel('id'); ?></dt>
             	<dd><?php echo $this->form->getInput('id'); ?></dd>
                <dt></dt><dd></dd>
        	    <dt><?php echo $this->form->getLabel('greeting'); ?></dt>
        	    <dd><?php echo $this->form->getInput('greeting'); ?></dd>
                <dt></dt><dd></dd>
                <dt></dt>
            	<dd><input type="hidden" name="option" value="com_helloworld" />
            	    <input type="hidden" name="task" value="updhelloworld.submit" />
                </dd>
                <dt></dt>
                <dd><button type="submit" class="button"><?php echo JText::_('Submit'); ?></button>
			                <?php echo JHtml::_('form.token'); ?>
                </dd>
        	</dl>
        </fieldset>
    </form>
    <div class="clr"></div>

This layout utilises the forms design which resides with the related model. The getLabel and getInput will pickup the xml fields defined and display appropriately. More on the xml file within the models section of this tutorial.

Create a file site/views/updhelloworld/tmpl/default.xml containing

site/views/updhelloworld/tmpl/default.xml

<?xml version="1.0" encoding="utf-8"?>
<metadata>
	<layout title="COM_HELLOWORLD_UPDHELLOWORLD_VIEW_DEFAULT_TITLE">
		<message>COM_HELLOWORLD_UPDHELLOWORLD_VIEW_DEFAULT_DESC</message>
	</layout>
</metadata>

This enables a menu option to be allocated to the frontend form.

Create the model[edit]

The UpdHelloWorld model sets up the data through from the related form and allows the mechanism to save the subsequent data loaded into the form into the database.

site/models/updhelloworld.php

<?php
// No direct access to this file
defined('_JEXEC') or die('Restricted access');
 
// Include dependancy of the main model form
jimport('joomla.application.component.modelform');
// import Joomla modelitem library
jimport('joomla.application.component.modelitem');
// Include dependancy of the dispatcher
jimport('joomla.event.dispatcher');

/**
 * UpdHelloWorld Model
 */
class HelloWorldModelUpdHelloWorld extends JModelForm
{
	/**
	 * @var object item
	 */
	protected $item;

	/**
	 * Get the data for a new qualification
	 */
	public function getForm($data = array(), $loadData = true)
	{

        $app = JFactory::getApplication('site');

        // Get the form.
		$form = $this->loadForm('com_helloworld.updhelloworld', 'updhelloworld', array('control' => 'jform', 'load_data' => true));
		if (empty($form)) {
			return false;
		}
		return $form;

	}

	/**
	 * Get the message
	 * @return object The message to be displayed to the user
	 */
	function &getItem()
	{

		if (!isset($this->_item))
		{
			$cache = JFactory::getCache('com_helloworld', '');
			$id = $this->getState('helloworld.id');
			$this->_item =  $cache->get($id);
			if ($this->_item === false) {

			}
		}
		return $this->_item;

	}

	public function updItem($data)
	{
        // set the variables from the passed data
        $id = $data['id'];
        $greeting = $data['greeting'];

        // set the data into a query to update the record
		$db		= $this->getDbo();
		$query	= $db->getQuery(true);
        $query->clear();
		$query->update(' #__helloworld ');
		$query->set(' greeting = '.$db->Quote($greeting) );
		$query->where(' id = ' . (int) $id );

		$db->setQuery((string)$query);

        if (!$db->query()) {
            JError::raiseError(500, $db->getErrorMsg());
        	return false;
        } else {
        	return true;
		}
	}
}

The following file updhelloworld.xml should be created using your favourite editor and saved in the forms folder under the models directory. The first of the fields being referenced id using the sql type so that I returns the results from the query into a dropdown list form to be selected. site/models/forms/updhelloworld.xml

<?xml version="1.0" encoding="UTF-8"?>
<form name="updhelloworld">
	<fieldset name="updhelloworld">

        <field
            name="id"
            type="sql"
            multiple="false"
            size="1"
            label="COM_HELLOWORLD_FORM_LBL_UPDHELLOWORLD_ID"
            description="COM_HELLOWORLD_FORM_DESC_UPDHELLOWORLD_ID"
            query="select id, greeting from #__helloworld"
            key_field="id"
            value_field="greeting"
            default="0"
	    required="true"
            >
                <option value="">JOPTION_SELECT_ID</option>
        </field>

	<field
            name="greeting"
            type="text"
	    description="COM_HELLOWORLD_FORM_DESC_UPDHELLOWORLD_GREETING"
	    label="COM_HELLOWORLD_FORM_LBL_UPDHELLOWORLD_GREETING"
	    required="true"
	    size="50" />

	</fieldset>
</form>

Adding some language keys[edit]

This file provides the text link between the label in the model form definition to be displayed in the view. And being for the frontend, it resides in the site folder.

site/language/en-GB/en-GB.com_helloworld.ini

COM_HELLOWORLD_FORM_LBL_UPDHELLOWORLD_ID="Greeting ID"
COM_HELLOWORLD_FORM_DESC_UPDHELLOWORLD_ID="This is the ID of the Greeting record"
COM_HELLOWORLD_FORM_LBL_UPDHELLOWORLD_GREETING="Greeting"
COM_HELLOWORLD_FORM_DESC_UPDHELLOWORLD_GREETING="Greeting description"
JOPTION_SELECT_ID=" -- Select Greeting to Update -- "

Add the last 2 lines to the admin/language/en-GB/en-GB.com_helloworld.sys.ini file to provide the text link for the menu type display. And being for the backend, it resides in the admin language folder.

admin/language/en-GB/en-GB.com_helloworld.sys.ini

COM_HELLOWORLD="Hello World!"
COM_HELLOWORLD_DESCRIPTION="This is the Hello World description"
COM_HELLOWORLD_HELLOWORLD_VIEW_DEFAULT_DESC="This view displays a selected message"
COM_HELLOWORLD_HELLOWORLD_VIEW_DEFAULT_TITLE="Hello World"
COM_HELLOWORLD_INSTALL_TEXT="HelloWorld Install script"
COM_HELLOWORLD_MENU="Hello World!"
COM_HELLOWORLD_POSTFLIGHT_DISCOVER_INSTALL_TEXT="HelloWorld postlight discover install script"
COM_HELLOWORLD_POSTFLIGHT_INSTALL_TEXT="HelloWorld postflight install script"
COM_HELLOWORLD_POSTFLIGHT_UNINSTALL_TEXT="HelloWorld postflight uninstall script"
COM_HELLOWORLD_POSTFLIGHT_UPDATE_TEXT="HelloWorld postflight update script"
COM_HELLOWORLD_PREFLIGHT_DISCOVER_INSTALL_TEXT="HelloWorld preflight discover install script"
COM_HELLOWORLD_PREFLIGHT_INSTALL_TEXT="HelloWorld preflight install script"
COM_HELLOWORLD_PREFLIGHT_UNINSTALL_TEXT="HelloWorld preflight uninstall script"
COM_HELLOWORLD_PREFLIGHT_UPDATE_TEXT="HelloWorld preflight update script"
COM_HELLOWORLD_UNINSTALL_TEXT="HelloWorld Uninstall script"
COM_HELLOWORLD_UPDATE_TEXT="HelloWorld Update script"
COM_HELLOWORLD_UPDHELLOWORLD_VIEW_DEFAULT_TITLE="Update the Greeting"
COM_HELLOWORLD_UPDHELLOWORLD_VIEW_DEFAULT_DESC="Update greeting here"



The _populateState method is, by default, automatically called when a state is read by the getState method.

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 conttraints -->
	<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.18</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>
		<folder>controllers</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>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/en-GB.com_helloworld.ini</language>
			<language tag="en-GB">language/en-GB/en-GB.com_helloworld.sys.ini</language>
		</languages>
	</administration>
 
	<!-- UPDATESERVER DEFINITION -->
	<updateservers>
		<!-- Note: No spaces or linebreaks allowed between the server tags -->
		<server type="extension" priority="1" name="HelloWorld Update Site">http://yourdomain.com/update/helloworld-update.xml</server>
	</updateservers>
 
</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.

Navigate[edit]

Prev: Adding an update server Next: Example of Menu Parameters & Stylesheets