phplaravellaravel-5routesrequest

Laravel route : any slug takes all the requests


I have a route something like this. The $slug is a variable that is matched to the slugs stored in the database to add the pages dynamically to the website.

#slug variable for different values of page slug....
Route::get('/{slug?}', array(
    'as' => 'page',
    'uses' => 'AbcController@renderPage'
));

However, now I wish to add an admin side of the website and want routes to be prefixed with media-manager.

My problem is, whenever I make a call to another route in the file, the above mentioned route takes the request call and calls the renderPage method every time, no matter wherever the request is coming from.

This is my middleware where I check for whether request is coming from a URL like 'media-manager/*', if so I don't want to check for the language of the website and redirect it to the media-manager's page.

private $openRoute = ['media-manager/login', 'media-manager/postLogin', 'media-manager/media'];

public function handle($request, Closure $next)
    {

        foreach ($this->openRoute as $route) {
            if ($request->is($route)) {
                return $next($request);
            }
        }


        // Make sure current locale exists.
        $lang = $request->segment(1);
        if(!isValidLang($lang)) {
            $lang = getDefaultLang();
            $segments = $request->segments();            
            array_unshift($segments, $lang);

            $newUrl = implode('/', $segments);
            if (array_key_exists('QUERY_STRING', $_SERVER))
                $newUrl .= '?'.$_SERVER['QUERY_STRING'];

            return $this->redirector->to($newUrl);
        }
        setLang($lang);
        return $next($request);
    }

This is the renderPage method where every time the request is being redirected, no matter what.

    public function renderPage($slug = '')
    {

        if ($slug == 'login') {
           return view ('site.login');
        }


        $page = Page::getBySlug($slug);
        if(empty($page)){
            return URL::to ('/');
        }

        if($slug == ''){//home page
            $testimonial = DB::table('testimonial')->where('lang','=',$this->lang)->get();
            $client_logo = DB::table('client_logo')->get();
            return View::make('index', compact('data','page', 'testimonial', 'client_logo'));

        }elseif($slug == 'services'){                
            return View::make('services', compact('page'));

        }elseif($slug == 'portfolio'){
            $categories = PortfolioCategory::getAll();
            $portfolio = Portfolio::getAll();
            return View::make('portfolio', compact('page', 'categories', 'portfolio'));

        }elseif($slug == 'oshara'){
            return View::make('oshara', compact('page'));

        }elseif($slug == 'blog'){
            $limit = 8;
            $pageNum = 1;

            $offset = ($pageNum-1)*$limit;
            $totalPosts = BlogPost::totalPosts();
            $totalPages  = ceil($totalPosts/$limit);
            $posts = BlogPost::getAll($offset, $limit);
            $blog_posts = View::make('partials.blog_posts', compact('posts','pageNum','totalPages'));
            return View::make('blog', compact('page', 'blog_posts', 'pageNum', 'totalPages'));

        }elseif($slug == 'contact'){
            $budgets = Budget::getAll();
            return View::make('contact', compact('page', 'budgets'));
        }
    }

This is postLogin method in the controller that I want to call after user clicks on Login button on login page.

public function postLogin($request) {
        # code...
        //$request = $this->request;
        $this->validate($request, [
           'email1' => 'required|email',
            'password' => 'required|string'
        ]);
        if($user = User::whereEmail($request->email1)->first() ) {
            if(Hash::check($request['password'], $user->getAttributes()['password'])) {

                if(!$user->getAttributes()['is_active']) {
                    return redirect('/media-manager/login')->withErrors('Your Account is not Activated Yet!');
                } else if($user->getAttributes()['is_deleted']) {
                    return redirect('/media-manager/login')->withErrors('Your Account is Banned!');
                } else {
                    # Success
                    $cookie = Cookie::make('user_id', $user->getAttributes()['id'], 864000);
                    //echo "hello";
                    return view('site.media')->with('message', 'You have Successfully Logged In!')->withCookie($cookie);
                }
            } else {
                return redirect('/media-manager/login')->withErrors('Your Login Information is Wrong!');
            }
        } else {
            return redirect('/media-manager/login')->withErrors('Your Login Information is Wrong!');
        }
    }

Can any one please suggest me some way so that I can disable renderPage method on every call and have my normal routing perform perfectly.


Solution

  • In Laravel the first matching route is used. So I would guess you have your slug route defined above the others (at least above the media-manager ones), right?

    So a simple solution would be to just put the slug route definition at the end of your routing file.

    Another approach would be utilize conditions for the route. For more information you can read this or leave a comment!

    Hope that helps!