Laravel redirect issue - php

I am using Laravel 4. When "logged_in_id" is found in session I want it to continue to parse through bellow written Routes.
Route::get('/{anything}', function($anything)
{
if(!Session::has('logged_in_id')) {
return View::make('user.login');
} else {
//continue to check Route::get written bellow this Routing
}
})->where('anything', '[A-Za-z0-9\/?=]+');
If I write Redirect::to('/'.$anything) then it enters the same Route and keeps on redirecting in loop. Is there any way to solve this problem?

I would create a filter and then apply it to any routes that need it.
Remember to put first the routes that are more restrictive and last the more generic ones.
See the example:
Route::filter('logged_in', function()
{
if(!Session::has('logged_in_id')) {
return View::make('user.login');
}
});
Route::get('testing', array(
'before' => 'logged_in',
function()
{
return View::make('user.testing');
}
));
Route::get('/{anything}', array(
'before' => 'logged_in',
function($anything)
{
return View::make('user.anything');
}
))->where('anything', '[A-Za-z0-9\/?=]+');

Related

Laravel Routing:: check parameter value and redirect

I have a route of GET type with some parameters. For example
Route::get('/my-route/{id}',array('uses'=>'myController#myAction'));
I want to check value of the parameter id and if this id=1 then redirect to another route else continue with it. What I am doing is like this
Route::get('/my-route/{id}',function($id){
if($id==1){
return Redirect::to(URL::route('my-another-route'));
}
else{
//What should I do here so my route works as before.
}
});
In else part I want my routes to myController#myAction along with parameters.
Thanks
You can do it as:
Route::get('/my-route/{id}',function($id){
if($id==1){
return Redirect::to(URL::route('my-another-route'));
}
else{
return app()->call(myController::class, ['id' => $id], 'myAction');
}
});
The easiest way to get this to work and route to your controller is put your Route back to the way it was and then the if statement to the top of your controller condition:
public function myAction() {
if ($id == 1) {
return Redirect::to(URL::route('my-another-route'));
}
to the top of your controller method.
Also, if you're only using uses => 'Controller#method' on with your route you can just do:
Route::get('/my-route/{id}','myController#myAction');
Hope this helps!

Laravel 5 conditional routing and multiple controllers

So basically my app has two types of dynamic url..
app.com/{page}
app.com/{user}
Both having their own controllers
PageController#index
User\ProfileController#index
But I'm struggling to get this working.
I have tried a few different methods. Here are two I have tried..
Route::get('{slug}', function($slug) {
if (App\Page::where('slug', $slug)->count()) {
// return redirect()->action('PageController#index', [$slug]);
// return App::make('App\Http\Controllers\PageController', [$slug])->index();
return 'Page found';
} else if (App\User::where('username', $slug)->count()) {
// return redirect()->action('User\ProfileController#index', [$slug]);
// return App::make('App\Http\Controllers\User\ProfileController', [$slug])->index();
return 'User found';
} else {
return abort(404);
}
});
I feel I should be doing this with middleware/filters. Any help would be great. Thanks.
I think you could achieve what you after with Route::group using a middleware to filter if it is a page or a user.
Route::group(['middleware' => 'isPage'], function () {
Route::get('{slug}', ['as'=> 'pages.show', 'uses' => 'PageController#show']);
});
Route::group(['middleware' => 'isUser'], function () {
Route::get('{slug}', ['as'=> 'users.show', 'uses' => 'User\ProfileController#show']);
});
If you were using slugs for the Pages and ids for the Users, your idea of handling the issue might make more sense, but since you are using slugs for both the pages and the users, I strongly suggest you try a different approach. Why not declare two routes? Why not use the "show" methods of the respective controllers while you are at it, and keep in line with conventions for resources?
Route::get('pages/{slug}', ['as'=> 'pages.show', 'uses' => 'PageController#show']);
Route::get('users/{slug}', ['as'=> 'users.show', 'uses' => 'User\ProfileController#show']);
And if you really want to keep your "root-slug-respective-redirect" functionality you could write afterwards:
Route::get('{slug}', function($slug) {
if (App\Page::where('slug', $slug)->count()) {
return redirect(route('pages.show', $slug));
} else if (App\User::where('username', $slug)->count()) {
return redirect(route('users.show', $slug));
}
return abort(404);
});
I do advise against it though, as it seems like a waste of queries.
Here are the docs on Laravel RESTful resource controllers for good measure.

How to redirect if the page is empty

I have a problem in Cake 3 whereby I want to have a controller check to see if its associated table is empty. If it is, it should forward to /add rather than list the empty index page.
Right now the url /introduction/index shows an empty index page, I'd like users to be automatically redirected to /introduction/add so they can get on with adding an entry.
If the id column of the DB has an entry, they should remain at the index. Hope that makes sense.
I tried the following in introductionController.php:
public function emptycheck()
{
$introduction = $this->Introduction->get($id);
if ($id = null) {
return $this->redirect(['action' => 'add']);
} else {
return $this->redirect(['action' => 'index']);
}
}
It does nothing, but I took some solace in the fact it didn't produce errors. How can I check if there is a record and redirect if there isn't?
In CakePhp there is the isEmpty() method to use.
$results = $this->Introduction->find('all');
if ($results->isEmpty()) {
return $this->redirect(['action' => 'add']);
} else {
return $this->redirect(['action' => 'index']);
}
There is the related documentation here
A different issue I see here is, that the configuration doesn't follow CakePhp conventions, about the use of plural and singular form of names. These conventions are here
This worked in the controller, appending the index() function like so:
public function index()
{
$this->set('introduction', $this->paginate($this->Introduction));
$this->set('_serialize', ['introduction']);
$introduction = $this->Introduction->find()->all();
if ($introduction->isEmpty()) {
return $this->redirect(
['controller' => 'Introduction', 'action' => 'add']
);
} else {
return $this->redirect('/introduction/index');
}
}
Thanks for the help.

How to make a route filters base on user type in Laravel 4?

Goal: I want to make route filter in Laravel 4 using Route::group and Route::filter
Description
I have 2 types of user :
Internal
Distributor
For, Internal, I have 2 groups:
admin
regular
For Distributor, I have 4 groups:
gold
silver
bronze
oem
Eligible Route
OEM Distributor are eligible for only 5 routes.
Route::get('distributors/{id}', array('before' =>'profile', 'uses'=>'DistributorController#show'));
Route::get('distributors/{id}/edit', 'DistributorController#edit');
Route::put('distributors/{id}/update', array('as'=>'distributors.update', 'uses'=>'DistributorController#update'));
Route::get('catalog_downloads','CatalogDownloadController#index');
Route::get('catalog_downloads/{id}/download','CatalogDownloadController#file_download');
Regular Distributor are eligible for 8 routes.
Route::get('distributors/{id}', array('before' =>'profile', 'uses'=>'DistributorController#show'));
Route::get('distributors/{id}/edit', 'DistributorController#edit');
Route::put('distributors/{id}/update', array('as'=>'distributors.update', 'uses'=>'DistributorController#update'));
Route::get('catalog_downloads','CatalogDownloadController#index');
Route::get('catalog_downloads/{id}/download','CatalogDownloadController#file_download');
Route::get('marketing_materials','MarketingMaterialController#index');
Route::get('marketing_materials/{id}/download/thumb_path','MarketingMaterialController#thumb_download');
Route::get('marketing_materials/{id}/download/media_path','MarketingMaterialController#media_download');
Code
filters.php
routes.php.
Questions
Can someone please help me or at least direct me to the right direction ?
First off: It's not possibble to declare a route that results in the same URL twice. Whether it's in a group or not. (Well if you have a group with prefix it's possible because a prefix changes to URL of the route)
You have to solve this problem by intelligent filtering
This is the simplest solution I've come up with:
Route::filter('distributor', function(){
$user = Auth::user();
if($user->type == "Distributor"){
return true;
}
if (Request::ajax()){
return Response::make('Unauthorized', 404);
}
return View::make('errors.404_auth');
});
Route::filter('distributor.regular', function(){
$user = Auth::user();
if($user->type == "Distributor"){
if($user->distributor()->type != 'OEM'){
return true;
}
}
if (Request::ajax()){
return Response::make('Unauthorized', 404);
}
return View::make('errors.404_auth');
});
The distributor filter checks just if the user is of type Distributor. The second filter, distributor.regular, checks if the distributor is not an OEM. (If you're wondering, the dot in distributor.regular has no special function or deeper meaning. I just like to write it like that)
Route::group(['before' => 'distributor'], function(){
Route::get('distributors/{id}', array('before' =>'profile', 'uses'=>'DistributorController#show'));
Route::get('distributors/{id}/edit', 'DistributorController#edit');
Route::put('distributors/{id}/update', array('as'=>'distributors.update', 'uses'=>'DistributorController#update'));
Route::get('catalog_downloads','CatalogDownloadController#index');
Route::get('catalog_downloads/{id}/download','CatalogDownloadController#file_download');
Route::group(['before' => 'distributor.regular'], function(){
Route::get('catalog_downloads', 'CatalogDownloadController#index');
Route::get('catalog_downloads/{id}/download', 'CatalogDownloadController#file_download');
Route::get('marketing_materials', 'MarketingMaterialController#index');
Route::get('marketing_materials/{id}/download/thumb_path', 'MarketingMaterialController#thumb_download');
Route::get('marketing_materials/{id}/download/media_path', 'MarketingMaterialController#media_download');
});
});
This should already work with the use-cases you posted. However we can make the filters more flexible and also reduce redundant code.
function makeError404(){
if (Request::ajax()){
return Response::make('Unauthorized', 404);
}
return View::make('errors.404_auth');
}
Route::filter('distributor', function(){
$user = Auth::user();
if($user->type == "Distributor"){
return true;
}
return makeError404();
});
Route::filter('distributor.group', function($route, $request, $value){
$groups = explode(';', $value);
$user = Auth::user();
if($user->type == "Distributor"){
if(in_array($user->distributor()->type, $groups)){
return true;
}
}
return makeError404();
});
Now we can dynamically specify in which group the user has to be...
Route::group(['before' => 'distributor'], function(){
// distributor routes
Route::group(['before' => 'distributor.group:gold;silver;bronze'], function(){
// regular routes
});
});
You can follow a path like this
class UserController extends BaseController {
/**
* Instantiate a new UserController instance.
*/
public function __construct()
{
$this->beforeFilter('employee', array('only' => 'index'));
}
}

Laravel show page according to authentication status

Is there any way I can do this configuration in routes.php:
Route::get('/', function(){
if ( Auth::check() === FALSE )
{
return homeController#guest<--- Specific Controller's method
}
else
{
return homeController#logged <--- Specific Controller's method
}
});
I don't want to use redirect since I want to keep mysite.com/ as the main address.
Of course you can do everything directly in the route like #Ferticidios answer or have only one controller method like #maytham suggests. But you can also do exactly what you asked for:
Route::get('/', function(){
if ( Auth::check() === FALSE )
{
return App::make('homeController')->callAction('guest', array());
}
else
{
return App::make('homeController')->callAction('logged', array());
}
});
You can do something like this:
Route::get('/', function(){
if ( Auth::check() === FALSE )
{
//Do stuff... get data
return Response::view('guest')->with($data);
}
else
{
//Do stuff... get data
return Response::view('logged')->with($data);
}
});
This is what filters were designed to do in Laravel. There is already on for the built in Auth or you can create your own
Route::get('user', array('before' => 'auth', function()
{
return App::make('homeController')->callAction('logged');
}));
The default filters can be adjusted in app/filters.php
http://laravel.com/docs/4.2/routing#route-filters

Categories