0
votes

I'm creating an MVC Component for Joomla 2.5 as a front end to another PHP database system I've built. Instead of just wrapping the other system's web interface in the wrapper component I'm building a native Joomla component that talks calls methods in other system's classes.

As such I have implemented a HTML form in one of my views which is to accept some input obviously but also a file upload. From here the component should send this input to my class's method for processing it, then the response will be fed to a second Joomla component view.

It seems to me that the the handling of the input should be done in a Model and probably receiving the processed output should also be done by the model. The Controller would then feed the model data to the second view?

I've gone through the Developing a MVC Component tutorial but it doesn't really give me much of an idea of how this should work. Can anyone give me a rough psuedocode idea of how this should fit together or point me to an appropriate tutorial or example of another component that does a similar thing?

2
I was under the impression that the controller blindly handles the data and the model deals with the logic/processing of the data to be passed back onto the view. From what I understand, your process is missing the controller out completely by passing the data directly to the modelLiam Sorsby

2 Answers

2
votes

Short answer, Yes your model should handle all retrieving and saving of an items details i.e. its row in the database or physical files.

So, for a longer answer, take the way com_content works as an example.

In the front-end you create a new article (e.g. via "Submit an Article" item of the "User Menu"). This is sent of as a GET request, with values similar to this:

format="html"
itemid="999"
option="com_content"
view="form"
layout="edit"

This request travels as follow:

  1. index.php receives the request and

  2. com_content/content.php is called when the components is required (i.e. com_content entry point).

  3. content.php creates controller via the JController class.

  4. JController looks at the inputs (i.e. params sent in the original GET request), figures out what component it's in and tries to firstly load a file called controller.php in the extensions folder and then looks for a suitable class in that file. (In this case ContentController)

  5. content.php then tells the $controller object to call the execute() with the relevant task, using this $controller->execute(JRequest::getCmd('task'));

  6. As you can tell from the GET request, no task has been set in this case so the __default task is used ( $doTask = $this->taskMap['__default']; ) In a JController the default task defaults to display, unless you override it.

  7. This causes the display() method in the ContentController class (com_content/controller.php) to be called.

  8. After some basic checks display() then calls the parent version of itself i.e. parent::display($cachable, $safeurlparams);

  9. The JContoller version of display() does all the basic work like getting the view name (form) and layout (edit) and using those to load the right view object (ContentViewForm).

  10. Then it loads the model & adds it to the view as the default model. (In this case the model is contentModelForm) It loads the right model based on the view name (form) and the model_prefix for the component. The model_prefix is setup by JController during it's __construct() method, by taking the name of the component 'Content' & appending 'Model' to it.

  11. After a bit more setup, the display() method of the view ContentViewForm is called, which is where the model data is loaded (if we were editing an article the same calls to the model would load the existing article based on a extra parameter in the GET containing the article id a_id=99).
    It also loads the Article form (com_content/models/forms/article.xml) at this point for use in the tmpl file edit.php.

So, to setup the input side the content fields are coming from the model (albeit an empty model for a new article) and the attributes of the fields are defined in the models matching form.

The saving of changes to the Article form takes a very similar path.

  1. GET portion of the request contains your article id (a_id=99) and the option parameter that point Joomla at your component ( option="com_content" )

  2. POST portion contains the form (jform) as an array, the task being performed ( task=article.save ) and a few other housekeeping parameters.

  3. As a result the controller type instantiated by JController this time is a ContentControllerArticle which extends JControllerForm (which is used for handling form submissions etc).
    Remember that dot notation task values are of the form [sub]controller.method.

  4. The save() method of the ContentControllerArticle object is called briefly before calling it's parent save() method in JControllerForm.

  5. At this point the save() method does things like check access permissions, validate data against any validations defined in the form and then load the model and passes the form data to the models save() method.

Does that help?

1
votes

I don't think you need to use the model to retrieve the data. It should be done in the controller part.

Assume the following is a function is a controller (you can call this function as task).

public function someFunction(){
     // retrive data from the form coming via $_POST (and consider sanitizing it)
        $data = JFactory::getApplication()->input->get('id', null, 'post');                 

      /*get model. You can call any model you want. 
       You can even call multiple models using this function
      */such as $model2 = getModel('SecondModel'); $model3 = getModel('ThirdModel');
        $model = $this->getModel('FirstModel'); //FirstModel should be an existing model
        $model->save($data);
        $formatted_data = $model->getData();

        $view=& $this->getView('OtherView','html'); //call any view you like
        $layout=JRequest::getVar('tmpl','default'); //instead of default you can use other template you prepared (such as edit...)
        $view->setLayout($layout); //bind the layout to the view
        //Pass the value to view. You can access this value in view as $this->formatted_data; later
        $view->set('formatted_data',$formatted_data);

       /*Call the view's display. 
        If you prepare other function in your view other than display, 
        you can use this function too. e.g. $view->display_report();
        But make sure you call parent::display() inside the function.
       */
       $view->display();
}