How To Publish with Backend Controller and Models in Joomla

While the majority of the request going to Joomla end up displaying a view, this is not the case for all of them. When records are published from a backend list screen, a controller task is called to do the publishing. To handle publishing in backend tasks Joomla has specially coded controllers and models.

So let's add some of those controllers and models now to our backend. First, let's login to the backend and now let's go to Components>Noida City>Noida City Places.

List screen of joomla backend

So this is a list screen that we have created in our previous tutorial. If we click on Publish or Unpublish buttons right now, nothing happens because we haven't added some things that we need for the view and we also need to add some controllers and model code to make this all work.

Creating model file in the backend

Let's get it working, go to administrator>component>com_noidacity>models folder and create a file called place.php and add the following code.

  1. <?php
  2. defined( '_JEXEC' ) or die;
  3.  
  4. jimport('joomla.application.component.modeladmin');
  5.  
  6. class NoidaCityModelPlace extends JModelAdmin
  7. {
  8. public function getTable($type = 'Place', $prefix = 'NoidaCityTable', $config = array())
  9. {
  10. return JTable::getInstance($type, $prefix, $config);
  11. }
  12.  
  13. public function getForm($data = array(), $loadData = true)
  14. {
  15. $form = $this->loadForm();
  16.  
  17. return $form;
  18. }
  19. }

So this is a model and it's a type of model that is the admin model. It's not a list model or does a plain model, it's an admin model and Joomla knows that admin models are used to work with specific rows in the database and because of that it's going to need to know which kind of row we want to work with.

  1. public function getTable($type = 'Place', $prefix = 'NoidaCityTable', $config = array())
  2. {
  3. return JTable::getInstance($type, $prefix, $config);
  4. }

So to do that we have a getTable function and that is going to return a JTable object, just like we used in the front end to display a single record from the database and we are just adding the type of record that it is and the prefix and it's going to assemble all of that together to load up the NoidaCityTable Place class, create an object and return it.

  1. public function getForm($data = array(), $loadData = true)
  2. {
  3. $form = $this->loadForm();
  4.  
  5. return $form;
  6. }

And then next the model also makes us define the getForm function. We are not really dealing with the form that's going to edit the place yet, but we're still required to define it by the JmodelAdmin class. So we just define getForm and we calling this loadForm and that's enough to make Joomla be happy with the modelAdmin class that we are defining here.

So after we are done with that, let's go and add the controller that is going to receive the tasks from the toolbar buttons and talk with the model.

Creating a controller called places

So just go to administrator>components>com_noidacity create a folder called controllers in the backend. And inside that create a file called places.php and inside that file write the following code.

  1. <?php
  2. defined( '_JEXEC' ) or die;
  3.  
  4. jimport('joomla.application.component.controlleradmin');
  5.  
  6. class NoidaCityControllerPlaces extends JControllerAdmin
  7. {
  8. protected $text_prefix = 'COM_NOIDACITY_PLACES';
  9.  
  10. public function getModel($name = 'Place', $prefix = 'NoidaCityModel', $config = array('ignore_request' => true))
  11. {
  12. $model = parent::getModel($name, $prefix, $config);
  13.  
  14. return $model;
  15. }
  16. }
  1. class NoidaCityControllerPlaces extends JControllerAdmin
  2. {
  3. protected $text_prefix = 'COM_NOIDACITY_PLACES';

We have a JControllerAdmin class, It starts off with a protected property called text_prefix and this is used for the language strings because we're going to have some status message updates that appear on screen and we need to know what prefix to use to assemble those language strings. So COM_NOIDACITY_PLACES is a prefix we are using and we are just defining it here.

  1. public function getModel($name = 'Place', $prefix = 'NoidaCityModel', $config = array('ignore_request' => true))
  2. {
  3. $model = parent::getModel($name, $prefix, $config);
  4.  
  5. return $model;
  6. }

And now the JControllerAdmin class wants us to define a getmodel function, so that it knows what model to get so that we can use that to talk to the database, when we are dealing with individual records. That getmodel function takes the name of the model and then the prefix with their model, and then it assembles all that for NoidaCityPlace, and then it loads up the Place model and just returns it. And in that way the different tasks that are embedded in JControllerAdmin can call up that model and work with the table.

So finally we need to update the view with a little bit of code that allows those toolbar buttons to work, so that way it actually does something and submits the form.

Tmpl folder opening default

Go to views>places>tmpl folder and open default.php file and add the following three lines of code just above the closing form tag.

  1. <input type="hidden" name="task" value="" />
  2. <input type="hidden" name="boxchecked" value="0" />
  3. <?php echo JHTML::_('form.token'); ?>

So now your default.php file which we created earlier will be like this:

  1. <?php defined( '_JEXEC' ) or die; ?>
  2. <form action="index.php?option=com_noidacity&amp;view=places" method="post" name="adminForm" id="adminForm">
  3.  
  4. <table class="adminList">
  5. <thead>
  6. <tr>
  7. <th width="1%">
  8. <input type="checkbox" name="checkall-toggle" value=""
  9. onclick="checkAll(this)" />
  10. </th>
  11. <th><?php echo JText::_('COM_NOIDACITY_FIELD_PLACE_NAME_LABEL'); ?></th>
  12. <th><?php echo JText::_('COM_NOIDACITY_FIELD_PLACE_DESCRIPTION_LABEL'); ?></th>
  13. <th><?php echo JText::_('JSTATUS'); ?></th>
  14. </tr>
  15. </thead>
  16. <tbody>
  17. <?php foreach($this->items as $i => $item): ?>
  18. <tr class="row<?php echo $i % 2 ?>">
  19. <td class="center">
  20. <?php echo JHTML::_('grid.id', $i, $item->place_id); ?>
  21. </td>
  22. <td>
  23. <a href="<?php echo $item->url; ?>"><?php echo $this->escape($item->place_name);?></a>
  24. </td>
  25. <td><?php echo $this->escape($item->place_description); ?></td>
  26. <td class="center">
  27. <?php echo JHTML::_('jgrid.published', $item->published, $i, 'places', 'cb');?>
  28. </td>
  29. </tr>
  30. <?php endforeach; ?>
  31. </tbody>
  32. </table>
  33.  
  34. <input type="hidden" name="task" value="" />
  35. <input type="hidden" name="boxchecked" value="0" />
  36. <?php echo JHTML::_('form.token'); ?>
  37. </form>
  1. <input type="hidden" name="task" value="" />

So you'll notice the first element is the hidden task element and this element is here so that whenever we click on one of the toolbar buttons, the toolbar button will take the task that's been assigned to it and assigned it as the value here and then submit the form.

  1. <input type="hidden" name="boxchecked" value="0" />

Next, we have the boxchecked hidden element and what this element does, is it keeps track of how many check boxes have been checked off on the left side of the screen.

  1. <?php echo JHTML::_('form.token'); ?>

And then finally we have this form token element at the bottom and what this does is it checks cross site request forgery attacks. It makes sure that the person that is submitting this form is the actual person that did it and not some other script that's on the Internet.

Clicking on unpublish button

Go back to the backend and hit Refresh and when we check off a couple of these records and hit Unpublish, it now unpublishes those records and it says 2 places unpublished.

So what happened is there is a task for Unpublish called places.unpublish that we added to our view in the toolbar in our previous tutorial, it's submitted that the form along with the values in these two check boxes, told the controller to unpublish those records, then the control pass those to the model and the model did the work of unpublishing the records. Then the controller redirected the browser back to the places view.

So when you want to do something aside from displaying views, that task built into ControllerAdmin will handle most of your backend needs. Hooking a modelAdmin class will give your ControllerAdmin the ability to talk to the database. And having the right HTML variables into view, make it possible for users to fire specific task by clicking at toolbar button.