J1.5

Difference between revisions of "Developing a MVC Component/Basic Backend Framework"

From Joomla! Documentation

< J1.5:Developing a MVC Component
Line 276: Line 276:
 
== Conclusion ==
 
== Conclusion ==
  
We have now implemented a basic framework for the backend admin component. A list with all Hellos is displayed. The next chapter will extend this framework and add user interaction / database manipulation.
+
We have now implemented a basic framework for the backend admin component. A list where all of the Hellos are displayed. The next chapter will extend this framework and add user interaction / database manipulation.
  
 
== Articles in this Series ==
 
== Articles in this Series ==

Revision as of 19:56, 20 August 2009

The "J1.5" namespace is an archived namespace. This page contains information for a Joomla! version which is no longer supported. 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 article focuses on the entry page/article for the administrator. Whilst the MVC pattern is the same as for the frontend user, this chapter will rapidly go though all steps and setup the backend counter part in the admin section. This article will only focus on setting up the Basic Framework with a list of all the Hellos but without user interaction. The actual user interaction is added in the succeeding article Developing a Model-View-Controller Component - Part 6 - Adding Backend Actions.

Creating the Basic Framework[edit]

The basic framework of the administrator panel is very similar to the site portion. The main entry point for the administrator section of the component is hello.php. This file is identical to the hello.php file that was used in the site portion except the name of the controller it loads will be changed to HellosController. The default controller is also called controller.php and this file is identical to the default controller in the site portion, with the exception that the controller is named HellosController instead of HelloController. This difference is so that JController will by default load the hellos view, which will display a list of our greetings.

Here is the listing for hello.php:

<?php
/**
 * @package    Joomla.Tutorials
 * @subpackage Components
 * @link http://docs.joomla.org/Developing_a_Model-View-Controller_Component_-_Part_4
 * @license    GNU/GPL
*/

// No direct access

defined( '_JEXEC' ) or die( 'Restricted access' );

// Require the base controller

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

// Require specific controller if requested
if($controller = JRequest::getWord('controller')) {
    $path = JPATH_COMPONENT.DS.'controllers'.DS.$controller.'.php';
    if (file_exists($path)) {
        require_once $path;
    } else {
        $controller = '';
    }
}

// Create the controller
$classname    = 'HellosController'.$controller;
$controller   = new $classname( );

// Perform the Request task
$controller->execute( JRequest::getVar( 'task' ) );

// Redirect if set by the controller
$controller->redirect();

The view and model that we will start with is the hellos view and the hellos model. We will start with the model.

The Hellos Model[edit]

The Hellos Model will be very simple. The only operation that we currently need is the ability to retrieve the list of hellos from the database. This operation will be implemented in a method called getData().

The JModel class has a built in protected method called _getList(). This method can be used to simplify the task of retrieving a list of records from the database. We simply need to pass it the query and it will return the list of records.

At a later point in time, we might want to use our query from within another method. Therefore, we will create a private method called _buildQuery() which will return the query that will be passed to _getList(). This makes it easier to change the query as well since it is localized in one place.

Therefore we need two methods in our class: getData() and _buildQuery().

_buildQuery() simply returns the query. It looks like:

/**
 * Returns the query
 * @return string The query to be used to retrieve the rows from the database
 */
function _buildQuery()
{
    $query = ' SELECT * '
           . ' FROM #__hello '
    ;

    return $query;
}

getData() will obtain the query and retrieve the records from the database. Now it might happen that we need to retrieve this list of data twice in one page load. It would be a waste to have to query the database twice. Therefore, we will have this method store the data in a protected property so that on subsequent requests it can simply return the data it has already retrieved. This property will be called _data. (<-- Naming convention conflict. Private or Protected data should be preceded with a '_' but as this reference is returned to the view where this data is directly accessed, this data can only be considered as public.)

Here is the getData() method:

/**
 * Retrieves the hello data
 * @return array Array of objects containing the data from the database
 */
function getData()
{
    // Lets load the data if it doesn't already exist
    if (empty( $this->_data ))
    {
        $query = $this->_buildQuery();
        $this->_data = $this->_getList( $query );
    }

    return $this->_data;
}

The completed model looks like:

<?php
/**
 * Hellos Model for Hello World Component
 * 
 * @package    Joomla.Tutorials
 * @subpackage Components
 * @link http://docs.joomla.org/Developing_a_Model-View-Controller_Component_-_Part_4
 * @license        GNU/GPL
 */

// Check to ensure this file is included in Joomla!
defined('_JEXEC') or die();

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

/**
 * Hello Model
 *
 * @package    Joomla.Tutorials
 * @subpackage Components
 */
class HellosModelHellos extends JModel
{
    /**
     * Hellos data array
     *
     * @var array
     */
    var $_data;

    /**
     * Returns the query
     * @return string The query to be used to retrieve the rows from the database
     */
    function _buildQuery()
    {
        $query = ' SELECT * '
            . ' FROM #__hello '
        ;
        return $query;
    }

    /**
     * Retrieves the hello data
     * @return array Array of objects containing the data from the database
     */
    function getData()
    {
        // Lets load the data if it doesn't already exist
        if (empty( $this->_data ))
        {
            $query = $this->_buildQuery();
            $this->_data = $this->_getList( $query );
        }

        return $this->_data;
    }
}

This file is saved as models/hellos.php.

The Hellos View[edit]

Now that we have a model to retrieve our data, we need to display it. This view will be fairly similar to the view from the site section as well.

Just as our model was automatically instantiated in the site, so it is in the administrator. Methods that start with get in the model can be accessed using the get() method of the JView class. So our view has three lines: one to retrieve the data from the model, one to push the data into the template, and one to invoke the display method to display the output. Thus we have:

<?php
/**
 * Hellos View for Hello World Component
 * 
 * @package    Joomla.Tutorials
 * @subpackage Components
 * @link http://docs.joomla.org/Developing_a_Model-View-Controller_Component_-_Part_4
 * @license        GNU/GPL
 */

// Check to ensure this file is included in Joomla!
defined('_JEXEC') or die();

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

/**
 * Hellos View
 *
 * @package    Joomla.Tutorials
 * @subpackage Components
 */
class HellosViewHellos extends JView
{
    /**
     * Hellos view display method
     * @return void
     **/
    function display($tpl = null)
    {
        JToolBarHelper::title( JText::_( 'Hello Manager' ), 'generic.png' );
        JToolBarHelper::deleteList();
        JToolBarHelper::editListX();
        JToolBarHelper::addNewX();

        // Get data from the model
        $items =& $this->get( 'Data');

        $this->assignRef( 'items', $items );

        parent::display($tpl);
    }
}

This file is saved as views/hellos/view.html.php.

Look carefully at the almost hidden differences compared to site example. The data is stored in a variable that is encapsulated within the model. Because the data amount is huge due to using the very handy _getList(), the need for returning a reference instead of a value is obvious. This is handled in:

$items =& $this->get( 'Data');

Looking again at this line and you will notice another difference with respect to the site view.html.php. The calling of the model function is done implicit. The actual model function name is getData(). In the site example you had to call following two lines:

$model =& $this->getModel();
$greeting = $model->getData();

Both lines are now taken care of by calling: $this->get( 'Data');. Under the surface of this get() the 'Data' is prefixed with 'get' so when using this function make sure the model functions are preceded with 'get'. This function can also be used in the site section; well to be honest it is good programming to keep the data in the model and address it by reference and this get() method is the preferred way of getting data from the model.

The Hellos Template[edit]

The template will take the data pushed into it from the view and produce the output. We will display our output in a simple table. While the frontend template was very simple, in the administrator we will need a minimal amount of extra logic to handle looping through the data.

Here is our template:

<?php defined('_JEXEC') or die('Restricted access'); ?>
<form action="index.php" method="post" name="adminForm">
<div id="editcell">
    <table class="adminlist">
    <thead>
        <tr>
            <th width="5">
                <?php echo JText::_( 'ID' ); ?>
            </th>
            <th>
                <?php echo JText::_( 'Greeting' ); ?>
            </th>
        </tr>            
    </thead>
    <?php
    $k = 0;
    for ($i=0, $n=count( $this->items ); $i < $n; $i++)
    {
        $row =& $this->items[$i];
        ?>
        <tr class="<?php echo "row$k"; ?>">
            <td>
                <?php echo $row->id; ?>
            </td>
            <td>
                <?php echo $row->greeting; ?>
            </td>
        </tr>
        <?php
        $k = 1 - $k;
    }
    ?>
    </table>
</div>

<input type="hidden" name="option" value="com_hello" />
<input type="hidden" name="task" value="" />
<input type="hidden" name="boxchecked" value="0" />
<input type="hidden" name="controller" value="hello" />

</form>

This template is saved as views/hellos/tmpl/default.php.

You will notice that our output is enclosed in a form. Though this is not necessary now, it will be soon.

We have now completed the basic part of the first view. We have added five files to the admin section of our component:

  • hello.php
  • controller.php
  • models/hellos.php
  • views/hellos/view.html.php
  • views/hellos/tmpl/default.php

You can now add these files to the XML install file and give it a try!

Conclusion[edit]

We have now implemented a basic framework for the backend admin component. A list where all of the Hellos are displayed. The next chapter will extend this framework and add user interaction / database manipulation.

Articles in this Series[edit]

Developing a Model-View-Controller Component - Part 1

Developing a Model-View-Controller Component - Part 2 - Adding a Model

Developing a Model-View-Controller Component - Part 3 - Using the Database

Developing a Model-View-Controller Component - Part 4 - Creating an Administrator Interface

Developing a Model-View-Controller Component - Part 5 - Basic Backend Framework

Developing a Model-View-Controller Component - Part 6 - Adding Backend Actions

Contributors[edit]

  • staalanden
  • jamesconroyuk

Download[edit]

The full admin component can be downloaded at: com_hello4_01.