I'm curious as to where to get data from JInput
in the MVC design pattern. For example, in a situation where I need a JInput
value to use in a query in a model class method, should I get the JInput
value there or should I pass it from the view or does it matter?
5 Answers
In a proper MVC structure, only your controller should interface with your request data, in this case JInput
, and the dependencies injected into the view and model when instantiated within the controller.
With the current CMS structure, all three pieces of the MVC structure are often interfacing with the request data. In models, this is usually done in the populateState()
method and views are more often in the layout files they are loading up than the actual class.
-
Thanks for the reply Michael. Would you mind explaining why it should theoretically be in the controller?– dooversApr 30, 2014 at 5:39
-
2Agree with Michael. Only the Controllers should be aware of request data. Model: Your DATA. View: The thing that controls how your data is PRESENTED. Controller: Sits between the data and the view, other data sources, and controls any changing of the data that needs to be done. Apr 30, 2014 at 5:54
-
It absolutely makes sense to me why request data should only be retrieved in the controller but is this even possible with the current Joomla MVC? Example: If you want to display a single item based on ID, you call $this->get('Item') in your View class to retrieve the data from your model. In your model's getItem method you could then get the ID from the request data ($id = JFactory::getApplication()->input->get('id')) and bring that ID into your SQL statement. Is there another way to do that?– fruppelApr 30, 2014 at 10:16
-
In the current architecture, no, it isn't possible to get that level of separation.– MichaelApr 30, 2014 at 16:12
-
@fl0r another way is to retrieve ID in the Controller and then to update the Model's state. May 1, 2014 at 14:35
I'm of the strong belief that it should be retrieved where appropriate.
That is to say you should always use JInput
otherwise you're duplicating data and potentially breaking DRY principles.
A view
class should be retrieving data to populate the the view
's templates (/tmpl
files) or layouts
from the model
, not injecting values into the model
. A view
after all is about presentation of data and UI not manipulation of data or handling of user actions.
-
1You might as well abandon the MVC completely when not following the rules!– sovainfoMay 1, 2014 at 15:13
-
Agreed… if we were talking about a real MVC implementation, but with Joomla's implementation of the MVC this isn't possible, see @Michael's answer below.– CraigMay 1, 2014 at 21:58
-
The whole purpose of MVC is doing things where they are supposed to. The fact that Joomla MVC is not 'real MVC' doesn't mean you should throw all rules overboard.– sovainfoMay 1, 2014 at 22:30
-
I've tried to follow Joomla's examples per the core components which use populateState() in their models almost exclusively, hence my answer.– CraigMay 1, 2014 at 23:57
-
Maybe I misread 'where appropriate' in your answer. Nothing against following core, even when they are not according to 'real MVC'.– sovainfoMay 2, 2014 at 10:59
JInput doesn't offer such feature; so you might have to use $_POST.
if you can have the input be in the form of array (and use JInput::getArray() )
or
a json-encoded object (you use json_decode(JInput::getString()))
http://developer.joomla.org/manual/chap-Joomla_Platform_Manual-Input.html
Though already answered, I'll try to explain in my on perspective.
Joomla! is a really great and flexible MVC Implementation.
About your problem of populating a View, with data from Model, depending on the user submitted data through $_GET. Here is how I do it.
First thing I'd like to state is that Besides the common Models, Views and Controllers there is another category of files used widely in Joomla!, those are the mini-Controllers. Yup you read it correct.
These are the files directly inside the view folder.
Here are a few of them.
view.html.php
view.raw.php
view.pdf.php
Apart from serving the purpose of generating different types of output, they also serve as a controller(In a way).
So for case like yours, one doesn't have to involve controllers just to get the data from the model. All you have to do is get the submitted data using jinput sanitize it and the pass the data as an object or array or just plain variable, to the Model.
Heres an example:
view.html.php
<?php
//-- No direct access
defined('_JEXEC') || die('=;)');
class compoViewDashboard extends JViewLegacy {
public function display($tpl = null) {
if (JRequest::getVar('layout') == 'somelayout') {
$jinput = JFactory::getApplication()->input;
$data = $jinput->post->get('xyz', 'null', 'INT');
/* If you are calling method from other(different) model you can use the following one line else you can skip it. */
$this->setModel(JModelLegacy::getInstance('syllabus', 'compoModel'));
$model = $this->getModel('syllabus');
$this->courses= $model->getcourses($data);
}
parent::display($tpl);
}
}
Thats it.
Disclaimer:- Remember that this is my own implementation, and may not be that perfect way, so get this approved by the pros before using any of my code in production environment.
Note:- I know JRequest is deprecated, but its there to stay as per the Joomla! core team, since the core too uses it all over the place.
I will usually use JInput in the controller to route the request, then pass the request to the model via a registry object.
Ideally you'd be passing the request data to the controller from your router logic, in order to make DI easy in your controllers but...at least this way the request dependencies are injected into the model and I don't need access to JInput to test it.
Once I have the data in the model, I can use it to set the model state, then the controller injects that model into the view with all the data necessary to fulfill the view data reqs already loaded into its properties.