How to re-factor dynamic menu code to OOP in a MVC framework? I have a MVC framework, and I am struggling with the following dynamic menu code.

A menu is pretty much HTML, so technically it should reside in the View, but the dynamic part is driven by PHP and a config class that holds all the menu items.


Where would I place this class? (model layer, view, library, or helper folder)
How would I re-factor this to be OOP?
How would I deploy this from my View?


Note: It should all be in regards to MVC principles.

class Menu {
    public static function get() {
        $URI = $_SERVER['REQUEST_URI'];

        $user = new User();

        if (!$user-&gt;isLoggedIn()) {
            $navArr = Config::get('navigation');

            $navigation = '&lt;ul id="nav-left"&gt;' . PHP_EOL;

            foreach ($navArr as $name =&gt; $path) {
                $navigation .= '    &lt;li' . ((in_array($URI, $path)) ? ' class="active"' : false) . '&gt;&lt;a href="' . $path[1] . '"&gt;' . $name . '&lt;/a&gt;&lt;/li&gt;' . PHP_EOL;
            }

            $navigation .= '&lt;/ul&gt;' . PHP_EOL . PHP_EOL;
        } else {
            //logged off navigation
        }


        return $navigation;
    }
}
Ok, firstly, you never want HTML in your controller. Always keep your output in your view, your application flow in the controller and your business logic in the model. Otherwise, this breaks separation of concerns (SoC). See https://stackoverflow.com/questions/1376643/mvc-separation-of-concerns for a relevant answer. 

Below, I am defining two classes - URI and User. These two should exist in your MVC platform to handle URI and User based actions (checking if a user is logged in, checking for the current URI or Permalink, etc). These would likely be helpers. We will use these later on by injecting them into our Menu::get() function. 

# Placeholder classes URI and User, which handle all URI and User activity
class URI{
    # ...
}

class User{
    # ...
}


Below is the Menu class. Note that I namespaced it, considering its a helper, this would allow it to be called with full namespace path if you placed the helper directory into your autoloader. 

Note how we are injecting an instance of URI via parameter $uri, and an instance of User via parameter $user. This is Dependency Injection (see https://stackoverflow.com/questions/130794/what-is-dependency-injection). 

# Helper class "Menu"
namespace KidDiamond\MVC\Helpers;

class Menu {
    # Rather than defining a new User object, just inject the user object as a parameter
    public static function get(URI $uri, User $User){
        if (!$user-&gt;isLoggedIn()) {
            $navArr = Config::get('navigation');

            $menu = '&lt;ul id="nav-left"&gt;' . PHP_EOL;
            foreach ($navArr as $name =&gt; $path) {
                $xor_active = ((in_array($URI, $path)) ? ' class="active"' : false);
                $menu .= '\t&lt;li' . $xor_active . '&gt;&lt;a href="' . $path[1] . '"&gt;' . $name . '&lt;/a&gt;&lt;/li&gt;' . PHP_EOL;
            }
            $menu .= '&lt;/ul&gt;' . PHP_EOL . PHP_EOL;
        } else {
            # logged off navigation menu
        }


        return $menu;
    }
}


Now, we move on to the Controller. Notice how all its doing is maintaining an initialized $menu_helper variable. You could technically inject the Menu helper...but I personally prefer to initialize it to a property. 

The $data variable inside the index() method is automatically returned, and injected into our view, below. 

# Controller class HomeController
namespace KidDiamond\MVC\Controllers;

class HomeController extends \BaseController{
    private $menu_helper;

    public function __construct(){
        $this-&gt;menu_helper = new KidDiamond\MVC\Helpers\Menu;
    }

    public function index(){
        $data['dynamic-menu'] = $this-&gt;menu_helper();

        return $data;
    }
}


This is our (simple) view. Notice that we're using a templating system (Blade, Mustache, etc) to output our variable dynamic-menu which was in the $data array in our controller method. 

# View for /index
&lt;html&gt;
    &lt;head&gt;&lt;/head&gt;
    &lt;body&gt;
        &lt;div class="menu"&gt;
            {{dynamic-menu}}
        &lt;/div&gt;
    &lt;/body&gt;
&lt;/html&gt;


I hope this helps. Do note that the code above is completely untested and is only there to help point you in the right direction. There may be syntax errors and other general errors.