1

This question already has an answer here:

I use Laravel as a PHP framework, although the question is not exactly about laravel, more about structuring controller methods.

I have a route to orders page. Depending on the user role I need to include different views and I have different logic for each role. It looks like this:

    public function index()
    {
        switch ($this->user->role->name) {
            case 'admin': {
                // Some code
                break;
            }
            case 'customer': {
                // Some code
                break;
            }
            case 'manager': {
                // Some code
                break;
            }
        }
    }

I repeat this pattern for all routes which are accessible for many roles. I know that using repeatedly if/else, switch or this kind of stuff is not the best solution. Also the function becomes quite big (not much but depends on logic). Of course I can break it into 3 subfunctions lie (indexAdmin, indexManager, indexCustomer) but am still not sure if it's good.

Could anybody explain how to deal with it, preferably using Laravel (I use 5 dev version)?

Update

Here is the full code: http://laravel.io/bin/eDkmj

marked as duplicate by gnat, user40980, Jim G., user53019, Kilian Foth Nov 30 '14 at 15:21

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

  • 1
    Well, when we consider just some abstract examples with Classes & OOP & Polymorphism, I understand what is in this link. But I absolutely cannot understand how to apply polymorphism in such MVC structure. I wouldn't like to create AdminOrderController, CustomerOrderConstoller etc... – Victor Nov 28 '14 at 19:33
  • The "some code" is the most important part! It's the behaviour that presumably is different depending on role. If you could give us an example of what that difference is and help us to understand the behaviour then we can provide more advice. – RibaldEddie Nov 29 '14 at 5:17
  • Okay, I've added the full version of code. Usually it's something like that, I use different filters (where, orwhere), fetch only those orders which belong to somebody or fetch all orders for admin etc. Sometimes it becomes too long. I know I can actually move the code into model, thought I don't think the model should work with Input, and also I don't want to make a function with arguments like: function getOrders($managerId = null, $searchString = null ... ). So, how to deal with this code and how to make it look pretty? :) Thanks in advance! – Victor Nov 29 '14 at 6:41
  • As a first step, you can move the code blocks in the switch to functions of their own and call those functions from the switch. After that you could try to think of a more automatic mechanism of mapping the role to the role-specific function to call. – Bart van Ingen Schenau Nov 29 '14 at 7:07
  • I'm not really seeing a problem here. You could move your roles over to a database table, along with anything configurable about them, and then range over them. I would also try to break up some of the code into functions. What's the problem with a switch, again? – Greg Nov 29 '14 at 12:28
-1

I think that break into 3 functions like you said is the best alternative, mainly to separate the logic of each user.

Here's an example of how this can be made:

public function index() {
    $method = "index" . ucfirst($this->user->role->name);
    $this->$method();
}

private function indexAdmin() {
    // do stuff
}

private function indexCustomer() {
    // do stuff
}

private function indexManager() {
    // do stuff
}
  • As elegant as this approach may seem, it becomes very difficult to do any sort of static analysis on it to see where a given method is called from (even search won't find where indexAdmin() is invoked). This also has the possibility of opening up other security issues in the application if unintended functions can be invoked. – user40980 Nov 30 '14 at 0:15

Not the answer you're looking for? Browse other questions tagged or ask your own question.