Actions

J2.5

Difference between revisions of "Developing a MVC Component/Example of a frontend update function"

From Joomla! Documentation

< J2.5:Developing a MVC Component
m (removing heading, navigation box controlled now)
m (standard template call, Reason: parameter added to templates to allow for Reason:)
Line 1: Line 1:
{{incomplete}}  
+
{{review|technical|This article needs to be reviewed by someone who knows what they're doing.}}  
 
This tutorial is for {{JVer|1.6}} {{JVer|1.7}} {{JVer|2.5}}
 
This tutorial is for {{JVer|1.6}} {{JVer|1.7}} {{JVer|2.5}}
== Warning - this article needs to be reviewed by someone who knows what they're doing ==
 
 
{{Chunk:Developing a Model-View-Controller (MVC) Component for Joomla!2.5 - Contents}}
 
{{Chunk:Developing a Model-View-Controller (MVC) Component for Joomla!2.5 - Contents}}
  

Revision as of 14:40, 14 August 2012

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.


This tutorial is for Joomla 1.6 Joomla 1.7 Joomla 2.5


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.

Basic frontend form

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

Create the specific controller

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

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

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

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

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>
                <filename>updhelloworld.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.

Zips

Download the zip file for this Part: [1]

Navigate

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

Contributors