2

I would like some help in using the delete() methods of the AdminController and AdminModel when in a front end list view to avoid duplicating code unnecessarily.

I have a listing of records in a frontend view for my component and I have added a checkbox for each line and a toolbar button to delete selected records. The delete button works in that the records selected in the view are available to the subcontroller via $this->input->get('cid', array(), 'array');

I have followed examples of how to put a method in my subcontroller that did enough to delete the records but some of the examples were more or less a cut and paste of the delete() methods in the AdminController and AdminModel. I would like to follow DRY principles and reduce my front in code where possible therefore I have been hacking away trying to invoke these Admin methods directly.

Links to the two classes I would like to use.

https://github.com/joomla/joomla-cms/blob/staging/libraries/src/MVC/Controller/AdminController.php

starting on line 111. and

https://github.com/joomla/joomla-cms/blob/staging/libraries/src/MVC/Model/AdminModel.php

starting on line 820.

Following the comment by Robbie Jackson I have updated the sample code to show what almost works.

In .../views/items/view.html.php I have this line for the toolbar button.

ToolbarHelper::deleteList('COM_INVENTORY_DELETE_CONFIRM','item.delete', 'COM_INVENTORY_DELETE_CONFIRM');

In .../model/item.php I now have

use Joomla\CMS\Factory;
use Joomla\CMS\MVC\Model\AdminModel;
use Joomla\CMS\Table\Table;
...
class InventoryModelItem extends AdminModel

In .../controller/item.php I have

use Joomla\CMS\Factory;
use Joomla\CMS\MVC\Controller\AdminController;
use ...


/**
 * Item controller class.
 */
class InventoryControllerItem extends AdminController
{
    .... unrelated methods ....

    public function delete()
    {
         ...
          $model = $this->getModel('Item', 'InventoryModel');
          $cid = ArrayHelper::toInteger($cid);
          if ($model->delete($cid))
          ...
     }

As well as extending the AdminController and AdminModel I had to replace $model = $this->getModel(); with $model = $this->getModel('Item', 'InventoryModel'); in my delete() method of the subcontroller to make it work. Without it $model was empty and it would fail on $model->delete($cid).

So while it can work, it still requires me to cut and paste the whole delete() method from AdminController just to specify my model, item, in item.php which is the default model.

There is something I am missing to make $this->model() find my model without me having to specify it implicitly.

Even any reference to help show how to use more Admin functionality in the front end would be appreciated, it sometimes feel like two different worlds. :)

4
  • What problems do you encounter if your controller and model classes inherit directly from AdminController and AdminModel? The example front-end form in docs.joomla.org/J3.x:Developing_an_MVC_Component/… has a model which extends AdminModel directly, although this is really for adding a record rather than deleting records. Commented Jan 13, 2020 at 12:24
  • @RobbieJackson thanks for replying. I have updated the second half of the question to show where I have got to now after reading your Joomla doc that shows it should be possible. To answer your question the $model is/was not being set causing the $model->delete() function in the model not to occur. While the delete function can work as I explained above it does cause another issue with getForm that I need to resolve now.
    – Irata
    Commented Jan 13, 2020 at 23:16
  • In your controller class you'll have to override the getModel function. So include: public function getModel($name = '', $prefix = '', $config = array()) { parent::getModel('Item', 'InventoryModel'); } (Sorry, it doesn't do nice formatting in comments) Commented Jan 14, 2020 at 16:27
  • @RobbieJackson Thank you, that worked. That method was in the controller at some earlier stage, from where ever I propagated it from, but I couldn't work out what purpose it served and I removed it, duh!. Now I know why it was there, thank you. If you could turn your comment into an Answer I will accept it.
    – Irata
    Commented Jan 14, 2020 at 21:31

1 Answer 1

1

I think it's unfortunate that Joomla's AdminModel and AdminController are named the way they are because it gives the impression that they're suitable for use only on the back-end, whereas that's not the case. The choice of which Joomla MVC model/controller your model/controller should extend ought to be based on what sort of functionality your web page is providing.

The advantage of choosing the best MVC class to extend is that it will already contain code which matches what you need, thus reducing the amount of custom code you need to write yourself. But it does require you to become familiar with the code in the "higher" Joomla MVC classes, and sometimes you need to add code in to your own model/controller because the Joomla code doesn't do exactly what fits your component.

Whilst the MVC View classes are named in a way that it's fairly clear what they should be used for, this isn't quite the same with the MVC Controller and Model classes. So here's my rough guide to the higher level MVC controller and model classes:

Models:

  • ItemModel – for displaying a single item
  • ListModel – for displaying multiple items
  • FormModel – for displaying a form which is defined in an XML file
  • AdminModel – for handling the database record updates required as a result of user action. AdminModel inherits from FormModel because validation of user data involves building the Joomla form, and so needs the methods from FormModel.

Controllers:

  • FormController – in a subcontroller handling HTTP POSTs, for handling the types of operations associated with editing or adding a single record (excludes delete)
  • AdminController – in a subcontroller handling HTTP POSTs, for handling the types of operations associated with multiple records (eg delete, reordering, batch operations). (Note that AdminController does not extend FormController).

Here are the conclusions I've come to regarding which MVC classes my own controller and model front-end classes should extend.

Simply displaying a record or a set of records, without providing the ability to change anything

  • controller extends BaseController
  • model extends BaseDatabaseModel or ItemModel if it's a single record, ListModel if it's multiple records.

Displaying a form with multiple records (but the form isn't defined in an XML file), including the providing the ability to select several records and apply some sort of operation to them (eg delete, publish):

  • controller extends BaseController
  • model extends ListModel – except if you're using the same model for displaying the form and handling the updates, in which case use AdminModel

Handling the HTTP POSTs from that form in subcontrollers:

  • controller extends AdminController
  • model extends AdminModel

Displaying a form with a single record, where the form is defined in an XML file, and allow the user to edit it, or a blank record and allowing the user to create a record:

  • controller extends BaseController
  • model extends FormModel – except if you're using the same model for displaying and form and handling the updates (as is usually the case I think), in which case use AdminModel

Handling the HTTP POSTs from that form in subcontrollers:

  • controller extends FormController
  • model extends AdminModel

The sort of additional changes you might have to make are typified by the question above, where you need to do the following to select the right model:

public function getModel($name = '', $prefix = '', $config = array()) 
{ 
    parent::getModel('Item', 'InventoryModel', $config); 
} 

See also https://stackoverflow.com/questions/21704490/what-are-the-differences-between-joomla-model-types/21710851#21710851

Note that this answer isn't saying that all Joomla functionality works the same on both front-end and back-end, eg https://github.com/joomla/joomla-cms/issues/5349

3
  • That is a very useful answer, it has helped a few more pieces fall into place for me. It is the sort of understanding document that should be available before newbies like me blindly follow docs.joomla.org/J3.x:Developing_an_MVC_Component/Introduction . I agree the use of the word Admin in the name is confusing particularly when you see it explained above and in your link to Valetin's post. And a sort of irony that you linked to issue 5349 as remembering what page I was on before an edit with pagination and populate state has been a pain for me. I could only up-vote once, sorry. :)
    – Irata
    Commented Jan 16, 2020 at 1:21
  • Thanks @Irata for that. Yeah, it's been on the back of my mind to write something in the Joomla docs to explain MVC better, because I too have found it all quite confusing and it's taken me a long time to get my head round it. So I'll definitely write something up on Joomla docs sometime soon. Commented Jan 16, 2020 at 13:17
  • @Irata - here's that page: docs.joomla.org/Model-View-Controller. I put a link to it in one of the MVC tutorial steps as well (Adding backend actions). Commented Jan 24, 2020 at 20:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.