2

I'm loading my NavHelper class in every controller of my imcro MVC framework by injecting it into my abstract controller. But should I really inject it in there?

The NavHelper class is actually meant for the View. It's got a static function that returns a dynamically built array of navigation items based on the current request URI. But how would I use that directly in a View since Views aren't suppose to worry about object creation?

Otherwise I'd have to load it in the controller like I'm doing now, and just repeat the following in every controller, which isn't DRY and then send that to the View.

View::render('nav', $nav->get());

Controller.php

abstract class Controller
{
    protected $req;
    protected $nav;

    public function __construct(Req $req, NavHelper $nav)
    {
        $this->req = $req;
        $this->nav = $nav;
    }
}
Kid Diamond
  • 2,232
  • 8
  • 37
  • 79
  • Don't know how your helper works - what it returns. If it's html then you should inject it into HtmlView object and pass data taken from model layer into it. If this helper is working more like a service then it belongs to model layer where it's preparing output data (from controller) for the view (or all kinds of views actually). This helper is unaware of many things (like: was URI valid? Doe's user has access to it?...) and shouldn't operate outside model unless its only display helper for html, but then it's even less aware. – shudder Jun 28 '14 at 19:48
  • It actually checks if user is logged in or not, and based on that returns the corresponding menu items in an array containing key value pairs like `'Name' => '/page'`. – Kid Diamond Jun 28 '14 at 20:28
  • @KidDiamond do you know what [Law of Demeter](http://c2.com/cgi/wiki?LawOfDemeter) is? Because that code of yours would be violating it. What's the damned point of passing something to the controller that your view needs? Why not pass it to the view in the first place? Of course that would assume that you actually have a fully realized view instance and not some faking template, that you like to pretend is a "view". – tereško Jun 29 '14 at 22:42

1 Answers1

1

It's model's job, so inject it there (or maybe include it's methods to some bigger class?). Also It depends on another model's object that has login information (usually User) so think about checking before building nav/pushing login data there/injecting User pointer (dpends on behaviour and amount of information needed). Example:

Model

//... has User and NavHelper injected
public function getNav() {
    return $this->navHelper->get($url_string, $this->user->loggedIn);
}

NavHelper

//...
public function get($url_string, $user_logged_in) {
    ...
    return $this->navArray;
}

View

//... has model pointer injected
private function renderNav() {
    foreach ($this->model->getNav() as $item => $url) { ... }
}

Ps. Try to avoid static methods - it has the same flaws as using globals (you cannot tell where it's used i.e. what depends on it and where it's state may change).

shudder
  • 2,076
  • 2
  • 20
  • 21
  • Tasks that relate to the visualization of navigation would be a part of UI logic. Do you agree? So .. emm ... why would you put UI logic in the model layer's code? Oh, and btw, **model is not a class or object**. – tereško Jun 29 '14 at 22:44
  • @tereško - I think that it's not View's concern what (data) will be displayed only how. If UI logic would decide what should it get I would have to rewrite it for every View and would still have to deal with the same data chunk at some point. Maybe I don't get something here - could you write your answer to clarify? – shudder Jun 30 '14 at 00:23
  • Please stop confusing [templates](http://chadminick.com/articles/simple-php-template-engine.html) with views. Maybe [this](http://stackoverflow.com/a/16596704/727208) will help you a bit. – tereško Jun 30 '14 at 00:25
  • @tereško "To create this response view acquires information from model layer" - still nothing. That's exactly what I wrote. – shudder Jun 30 '14 at 00:28
  • 1
    navigation is a concept of UI, it has **nothing** to do with model layer – tereško Jun 30 '14 at 00:29
  • @tereško But this helper doesn't provide UI itself - just data (That's why I asked for that in question comments). – shudder Jun 30 '14 at 00:41