2

I'm trying to understand MVC, and learning CI framework. I've some questions about MVC and some basic questions about CI.

1)Views are visual part of application as i read from tutorials, my question is: e.g There is a button "Login" but if user already logged in button will be "Logout". Where will that login check be? On controller or on view? i mean

   //this is view//

     <?php if($_SESSION('logged') == true):?>
     <a href="logout">Logout</a>
     <?php else: ?>
     <a href="login">login</a>        
     <?php endif; ?>

or

  //this is controller//

 if($_SESSION('logged') == true)
 $buttonVal = 'logout';
 else
 $buttonVal = 'login';

 //and we pass these value to view like
 $this->view->load('header',$someData);

 //this time view is like
 <a href="<?=$somedata['buttonVal']?>"><?=$somedata['buttonVal']?></a>

i just write theese codes as an example i know they wont work, they are imaginary codes, but i guess you got what i mean. Login check should be on controller or on view?

2)Should models contain only codes about data and return them to controller? For example there is a math, we get 2 value from database and multiply them and display them. Model will multiply or controller will do it?

here we load data with model and do math on controller: //model

   $db->query(....);
   $vars=$db->fetchAll();

   return $vars;

   //controller
   $multi = $vars[0] * $vars[1];
   $this-load->view('bla.php',$mutli);

here we load data with model and do math on model too, controller just passes data from model to view:

   //model

   $db->query(....);
   $vars=$db->fetchAll();
   $multi = $vars[0] * $vars[1];
   return $multi;

   //controller
   $multi = $this->model->multiply();
   $this-load->view('bla.php',$mutli);

i mean with that, models should do only database works and pass data to controllers, controller do rest of work and send view to render? Or models do work, controllers get them and send them to view?

3)This is about codeigniter, i have a header which has to be in every page, but it has javascripts,css depending to page i'm using

        <?php foreach ($styles as $style): ?>
        <link id="stil" href="<?= base_url() ?>/css/<?= $style ?>.css" rel="stylesheet" type="text/css" />
        <?php endforeach; ?>

this will be on every page, so in every controller i have

$data['styles'] = array('css1','css2');
$this->load->view('header', $headers);

i'm thinking to make a main controller, write this in it, and all my others controllers will extend this, i see something MY_Controller on CI wiki, is this MY_Controller same with what i'm doing? Are there any other ways to do this?

Sorry for bad English and dummy questions. Thanks for answers.

6
  • 4
    Since you are using CodeIgniter, you shouldn't worry about understanding MVC because you will have to unlearn all their misconceptions about it at a later stage. Just do what works now. Commented May 13, 2012 at 14:27
  • Look at this : Detailed Overview Of MVC Commented May 13, 2012 at 14:39
  • @Gordon Could you elaborate what these misconceptions are? Commented May 13, 2012 at 21:13
  • @Repox their user guide claims "Models are PHP classes that are designed to work with information in your database" and then goes on to show classes that have no other purpose than doing CRUD, giving the impression that Model == Database, which is wrong. Also what they call ActiveRecord is actually a very simple QueryBuilder. And I am sure there is more to find if you bother to take a deeper look at their code. Commented May 13, 2012 at 21:22
  • 1
    @Repox if they would clearly state that the Model is a layer made up of additional layers, like Service Layers, Domain Model, Persistence Layer, etc and is really the heart of your application then I wouldnt mind the CRUD examples but there is nothing like it and if you look at the questions on SO you'll see that CI users think Model is a class doing CRUD only. As for the AR, it's not even a modified version. AR is a row object with added business logic. Their modified version is nothing like that at all. I agree that there is many poor frameworks, but CI is one of the poorest. Commented May 13, 2012 at 21:47

3 Answers 3

5

This is absolutely view logic, the correct way to do it in my opinion:

 <?php if($logged_in):?>
 <a href="logout">Logout</a>
 <?php else: ?>
 <a href="login">login</a>        
 <?php endif; ?>

The value of $logged_in would probably be retrieved from a call to a library method:

<?php if ($this->auth->logged_in()): ?>

Authentication is one of those things you'll want access to globally, so you may be calling $this->auth->logged_in() in controller or views for different reasons (but probably not in models).

In every controller i have

$data['styles'] = array('css1','css2');
$this->load->view('header', $headers);

Yes you could extend the controller class with MY_Controller, but you're better off keeping this in the view/presentation layer. I usually create a master template:

<html>
<head><!-- load assets --></head>
<body id="my_page">
  <header />
  <?php $this->load->view($view); ?>
  <footer />
</body>
</html>

And write a little wrapper class for loading templates:

class Template {
  function load($view_file, $data) {
      $CI = &get_instance();
      $view = $CI->load->view($view_file, $data, TRUE);
      $CI->load->view('master', array('view' => $view));
  }
}

Usage in a controller:

$this->template->load('my_view', $some_data);

This saves you from loading header/footer repeatedly. In my opinion, presentation logic like which CSS file to load or what the page title should be belongs in the view whenever possible.

As far as models go, you want them to be reusable - so make them do what you need and keep it strictly related to data manipulation (usually just your database). Let your controller decide what to do with the data.

Not related to MVC, but in general you want to write as little code as possible. Redundancy is a sign that you could probably find a better solution. These are broad tips (as is your question) but hopefully it helps.

Sign up to request clarification or add additional context in comments.

Comments

-1

1) View logic should be simple and mostly if-then statements, if needed. In your example, either case would work but use the logic in the view. However, if you were checking for login and redirecting if not logged in, then that would occur in a controller (or a library).

2) Think of Codeigniter models as ways to access database functions - Create, Retrieve, Update, Delete. My (loose) rule of thumb is for Codeigniter models is to return results from update, delete or insert queries or a result set from a fetch query. Any applicable math can then occur in the controller. If this is a math operation that occurs EVERY time, consider adding it to a library function. See below...

3) Extending the controller is the proper and best way to accomplish this.

*) Not to add more to your plate, but also be sure to learn about Codeigniter Libraries. For example, in your controller you could load your library. You then call your library function from your controller. The library function calls a model which retrieves your database result. The library function then performs math on that function and returns the result to the controller. The controller is left with little code but a lot is accomplished due to the library and model.

7 Comments

-1 for "Think of models as database access functions". The Model is not just the database.
From the Codeigniter User Guide "Models are PHP classes that are designed to work with information in your database."
Model is more than just CRUD functions.
Codeigniter user guide shouldn't be something from where you take concepts. just saying.
@ChristopherIckes they are wrong. They also claim their QueryBuilder is an ActiveRecord, which it isn't.
|
-2

The user lo-gin check should be in the controller. This should be the first function that need to be invoked in the constructor.

Below i have given the sample code which redirects the user to the login page if he is not logged in, hope this would give you some idea,

<?php

class Summary extends Controller {

    function Summary() {
        parent::Controller();
        $this->is_logged_in();
    }

    function is_logged_in() {
        $logged_in = $this->session->userdata('logged_in');
        if (!isset($logged_in) || $logged_in != true) {
            $url = base_url() . 'index.php';
            redirect($url);
            exit();
        }
    }

?>

The button change can be implemented in the view by checking the session variable in view and making decisions accordingly.

Please take look at this link

1 Comment

You said The user lo-gin check should be in the controller. and then ended up writing the logic in view....

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.