0

I have to make some design decision in my application using Codeigniter.

I have a method in controller that calls a library for creating PDF. Also I have some class that takes a number as an argument and returns string (number verbally ).

I would like to know what is the bestr practice to pass data between all this class. Is this a task of controller to call all libraries (between step2 and step 3) and provide all prepared data to a model that will create PDF. Or is this a task of Model itself to transform provided raw data by loading and calling class that converts number to string.

What would be the best solution in terms of loose coupling and modularity and clarity of the code.

This is a controller:

class Payu extends CI_Controller
{
     public function raport($task_id)
     {
           /* (step 1) Load necessarty models */
           $this->load->model('MTasks');
           $this->load->model('mpdfinvoice');

           /* (step 2) task details from DB */
           $task_details = $this->MTasks->getTaskDetails($task_id);

           /* (step 3) create PDF that will be send */
           $this->mpdfinvoice->pdf($task_details);

           /* (step 4) compose an email with attached pdf */
           $this->email->from($this->config->item('noreply_email'));
           $this->email->to($task_details['email']);
           $this->email->attach('invoiceJustCreated.pdf');
           $this->email->subject('opłaciłes to zlecenie');
           $message = 'some message goes here';
           $this->email->message($message);
           $this->email->send();


     }
}


 This is a model that creates PDF file (called by controller)

 class mpdfinvoice extends CI_Model
 {
     public function pdf($task_details)
     {
          /* (step 1) load necesary library and helper */
          $this->load->library(array('fpdf' ));
          $this->load->helper('file');

          /* (step 2) set PDF page configuration*/              
          $this->fpdf->AddPage();
          $this->fpdf->AddFont('arialpl','','arialpl.php');
          $this->fpdf->SetFont('arialpl','',16);

          /* (step 3) show data on PDF page */              
          $this->fpdf->cell('','',$task_details['payment_amount'] ,1);

          /*  I want to have "payment amount" verbally here 
              So Should I load and call the convert class here or
              should I have this data already prepared by the controller
              and only output it ? */

     }
 }
tereško
  • 58,060
  • 25
  • 98
  • 150
  • In MVC the controller would only be responsible for passing appropriate data from user's request to the model layer. Nothing else. It should not be sending messages, rendering templates or anything like that. The bottom line is this: CodeIgniter does not implement MVC or MVC-inspired design pattern. – tereško Apr 04 '13 at 08:35
  • So Model should send emails ? What do You mean by that CodeIgniter does not implement MVC ? – czomberzdaniela Apr 04 '13 at 09:03
  • Model is not a class or object. It is a layer. You can read a longer explanation [here](http://stackoverflow.com/a/5864000/727208). As for CodeIgniter: it does not have views. Only simple, dumb templates. This forces UI logic in the "controllers", breaking the SoC for presentation layer. And in most implementations, there is no model layer. Only a collection of active-record based entities. That in turn forces the application logic in the controller, breaking the SoC between model layer and presentation layer. – tereško Apr 04 '13 at 09:07
  • Which framework is closest to correct implementation of MVC in Your opinion ? – czomberzdaniela Apr 04 '13 at 11:27
  • Frameworks do not implement MVC. And they should not claim that they do. Frameworks should provide tools, that let user to choose appropriate architecture. In the PHP-verse, the one that fit this description would be Zend Framework 2.x and Symfony 2.x .. also, it might be worth trying out the new Laravel, which has been moving away from rails-clone mentality. Then again, it is not necessary to use a framework, if you want to make a MVC-based application. And learning about MVC from frameworks is like learning good programming practices from Wordpress. – tereško Apr 04 '13 at 11:57

2 Answers2

0

I would suggest that the creation of the PDF or any other file and all the convertions between values to happen at the Model and then the Controller decide which data to fetch from the Model in order to pass it to the appropriate View and it will know how to display it.

Controllers should not be used to directly display(output) data or access database and do file creations.

Also Models should not ever be used to output data for any case.

Vassilis Barzokas
  • 3,105
  • 2
  • 26
  • 41
  • So i'm using model to save PDF on disk. So is this a rule that controller should not work on data fetched from model ? Isn't his role to load libraries and helpers ? – czomberzdaniela Apr 04 '13 at 08:33
  • No that's what i am trying to say. Controller SHOULD work on data fetched from Model, but not fetch them by itself. In your case i think that the function that does the conversion should better be a Helper if you need to use it both on Models and Controllers. You cannot (and should not) load a Controller's function within a Model. – Vassilis Barzokas Apr 04 '13 at 08:42
  • That's exactly what i'm trying to understand. If the conversion function is a helper (or library in my case) that can be loaded both by the model and the controlelr which place is better to perform such operation ? Where should I load and call helper/library - in controller or in model ? – czomberzdaniela Apr 04 '13 at 08:54
0

Try to look at controllers in codeigniter as your data glue. A controller retrieves data from clients, standardizes it and triggers the appropriate actions (redirect, triggering libraries, views, models and helpers while using the data provided.)

In your case just use a controller to retreive the data from your models or userinput. Then pass it to a library that creates the pdf. If the pdf creation is succesfull return true to let te controller know its a succes. Create a flashdata succes message and redirect to a page that outputs a view:

  1. User request: pdf/download
  2. Controller Pdf triggers the download method
  3. download triggers the models and pushes the data to a view
  4. The view with its data will be returned into a variable
  5. The $view variable will be pushed to a Pdf library
  6. trigger pdf create
  7. Pdf triggers pdf download (optional)
  8. Controller triggers redirect to pdf/overview
Chris Visser
  • 1,607
  • 12
  • 24
  • Just to be sure - This is the library (model precisely) that creates PDF which should load and call other helpers and libraries to convert and format raw data passed from controller ? – czomberzdaniela Apr 04 '13 at 08:41
  • 1
    I like to look at it from a restful perspective. For example: Order is an object, so you will have one model called Order, one controller called Orders and multiple views: list (multiple orders), detail, update. If you need orders in PDF format, load the PDF creator library. If this library depends on other libraries, helpers etc, NP! just use them. (personaly) I try to avoid library dependency on models, views or other controllers, but helpers and other libraries.. no problem. – Chris Visser Apr 04 '13 at 08:53