I know that to handle 404 errors with laravel 4 is to write at app/start/global.php :
App::missing(function($exception)
{
return Redirect::route('404_Error');
});
But actually I want to use this route:
Route::get('error', array(
'as' => '404_Error',
'uses' => 'ErrorController#get404Error'
));
But to stay at the same URL.
Example:
My URL right now is localhost:8000/users/blat (404 Error). I don't want redirect to error page. I want to see ErrorController#get404Error at this URL.
Thanks so much.
You may try something like this:
App::missing(function($exception)
{
return App::make('ErrorController')->get404Error($exception);
});
Your ErrorController:
class ErrorController extends BaseController {
//...
public function get404Error($exception)
{
//...
$data = ...;
return View::make('error_view')->with('data', $data);
}
}
If you use a different route it will redirect to that route, you probably will need to render your view right away, IMO it's the only way to stay where you are and not have your url changed:
App::missing(function($exception)
{
return View::make('404_Error');
});
You can just create an instance of the ErrorController class and call its get404Error method. That way you will have the variables from your BaseController class too and the route will stay the same.
App::missing(function($exception)
{
$errorController = new ErrorController();
return $errorController->get404Error();
});
Related
I have the next code:
Route::get('/{lang}/user/sort-by-{class}', function ($lang,$class) {
return view('users.list',compact("lang","class"));
})->where('class', '[a-z]+');
Route::get('/{lang}/user/{user}', function ($lang,$user) {
return view('users.user',compact("lang","user"));
});
When condition in where is false, how can I send it directly to 404 when sort-by- is for example a number? The problem is that it goes to secondary route as an user.
For example:
/en/user/sort-by-name is ok
/en/user/sort-by-4446 must show 404 page
I know that i can do another route just between them with
Route::get('/{lang}/user/sort-by-{class}', function ($lang,$class) {
return \Response::view('errors.404',array(),404);
})->where('class', '.*');
but this seems ugly, i would like in same sentence
Basically, you may do this
Route::get('/{lang}/user/sort-by-{class}', function ($lang,$class) {
if (is_numeric($class)) {
abort(404, 'Your reason');
}
return view('heros.list',compact("lang","class"));
});
Though, using closures in routes is a bad practice because they cannot be serialized in production mode. That's why you should use a controller to return your view, and assign a middleware to this route which will check your class and abort the request if needed.
I'm new to laravel and I have searched a lot for an answer to my problem but either it's not applicable or I'm not getting it.
I have a FileMaker solution for a client that handle customers and events. Each customer to my client have their own event websites that is managed via the solution. A cms simply. Each customer get a site with a url like clientsite.com/event.
Each page in the event has a page-type and I would like to address different controllers depending on the type.
In routes.php i have:
Route::group(['middleware' => ['sal', 'menu']], function () {
Route::get('/{event}/{page}', function($event, $page) {
// Query page for page-type and use controller depending on type
});
});
There are many page types (standard text/image, specialized forms etc) and therefor I would like to address different controllers.
Event names are always unique but pages are not.
You could call a controller manually inside the route closure. Though I would suggest doing the validation in a helper file to make the route file clean and readable.
Route::group(['middleware' => ['sal', 'menu']], function () {
Route::get('/{event}/{page}', function($event, $page) {
// you could do something like
$user_type = Auth::user()->user_type;
if($user_type == "organizer")
{
$controller = $app->make('OrganizerController');
return $controller->callAction('controllerFunc', $parameters = array());
}
else
{
$controller = $app->make('ClientController');
return $controller->callAction('controllerFunc', $parameters = array());
}
});
});
An alternative to the route solution could be to handle the logic in the controller itself:
First, update routes.php to something like:
Route::group(['middleware' => ['sal', 'menu']], function () {
Route::get('/{event}/{page}', 'RoutesController#index');
});
Then, in the RoutesController.php file (add to app/Http/Controllers), you can do something similar to:
public function index()
{
$event = Request::segment(1); // get the {event} part of the route
$page = Request::segment(2); // get the {page} part of the route
// get event data from database, e.g.
$event_data = Event::where( 'slug', $event )->first();
// load correct page
switch ( $page ) {
case "people":
return $this->people();
break;
case "anotherPage":
return $this->another_page();
break;
}
}
private function people()
{
// show view
return View::make('event.people');
}
This solution keeps your routes file clean, but also lets you handle the different event and page data, and load different views depending on the page being looked at. Your extra logic would be better in a controller rather than the routes file.
It all depends on where you prefer to code your page / view logic. You can use this approach call functions in the same controller, or external ones.
I have a url www.mywebsite.com/store/123456
where store is my controller class and I have a index function in it where Im getting the value after after store ,ie 123456.But im not able to achieve it.
As found online,I have tried adding this to routes $route['store/(:any)'] = 'store/index'; also tried
$route['store/(:any)'] = 'store/index/$1';
but doesn't seem to work.Please help me out.
In controller index function is
public function index()
{
echo $this->uri->segment(1);
}
But its not working.Pleae help
You are invoking 123456() method instead of index() method therefore you get CI's 404.
The simplest way is to use this kind of route
$route['store/(:any)'] = 'store/index/$1';
AND in top of it add parameter to index function in your case
public function index($parameter)
{
echo $this->uri->segment(2);
}
note that I changed segment parameter please see documentation.
using _remap()
function _remap($parameter){
$this->index($parameter);
}
function index($p)
{
echo $p; //shows 123456
}
If I remember correctly:
segment(n) gives you the segments of your uri before the routing takes place
rsegment(n) gives you the segments of your uri after routing (if routing occurred or the same as segment if it didn't)
so for /store/123456 getting rerouted to /store/index/123456
segment(1) == rsegment(1) == 'store'
rsegment(2) == 'index'
segment(2) == rsegment(3) == '123456'
Route:
$route['terms_and_conditions'] = 'SO_front/page/1';
controller :
public function page($id)
{
echo $id;
}
Output :
1
Here my solution for CI3...i would prefer laravel for advanced routing, orm,restapi, build in vuejs.
$route['store/(:any)'] = 'store/index/';
public function your index(){
$parameter=$this->uri->segment(2);
//use parameter for sql query.
}
Let say your route $route[store/product/update/(:any)] , then $parameter=$this->uri->segment(4)
Problem?. You will need to change entire file code if you plan to change the route name include view, controller, and custom route.
I am learning laravel 4.
The code of my route file:
Route::post('user/admin', 'UserController#admin');
Route::get('user/login', 'UserController#login');
Route::resource('user', 'UserController');
Route::get('/', function()
{
return View::make('home');
});
The code of my controller:
public function admin() {
$msg = Usr::get_data();
if ($msg == "pass") {
return View::make('user.admin');
} else {
return Redirect::to('user/login');
}
}
There is no problem when i use Redirect::to, but if i change to Redirect::route, it said route [user/login] is not defined. But I already defined it in the routes.php. Why Redirect::() does not work, and what is the difference between them?
Redirect::route is for a named route whereas Redirect::to is for any internal redirect. None of the routes you've added are named, so you cannot use Redirect::route to refer to them.
Redirect::to retrurns a redirect with the flash data
An example from the documentation
return Redirect::to('user/login')->with('message', 'Login Failed');
While Redirect::route Returnns A Redirect To A Named Route.
return Redirect::route('profile', array(1));
Check the documentation.It will make you understand better.
Edit:
Redirect::route() can redirect with a flash data too.
This is a fresh installation of Laravel 5.2, the only thing I did was to add a new column to the table users this new column is call roles which is just integers...
What I'm trying to do is to load a controller/view base on the information of this column...
Say if the column roles has a value of 1 then load the view X
in my routes file I have this
Route::group(['middleware' => ['web']], function () {
Route::auth();
if(Auth::user()->roles == '1') {
Route::get('/admin', 'AdminController#index');
Route::post('/admin', 'AdminController#save');
Route::get('/admin/{datas}', 'AdminController#datas');
Route::get('/admin/list', 'AdminController#list');
Route::get('/admin/list/{details}', 'AdminController#details');
} else {
Route::get('/login', 'UsersController#login');
}
if I use this Auth::user()->roles == '1' inside a view it "works" but is not what I want and I really don't want to install 3rd packages for user control, I just want something very simple... so how can I accomplish this?...
Based on what Matt said(I didn't get it at first, I'm new to laravel so bear with me), this is what I did...
Install a fresh laravel...
then run this php artisan make:auth, it will install everything you need for users to register/login/reset...
then open your AuthController.php change this protected $redirectTo = '/home' for whatever you want, in my case I called delegate $redirectTo = '/delegate'
then on your routers.php file put something like this
Route::group(['middleware' => ['web']], function () {
Route::auth();
Route::get('/delegate', 'DelegateController#index');
});
You don't actually need a view for this route, what you need is the controller...
On this controller DelegateController.php will put something like this
namespace App\Http\Controllers;
use App\Http\Requests;
use Auth;
use Illuminate\Http\Request;
// use App\Http\Controllers\Controller;
class AdminController extends Controller
{
public function __construct()
{
$this->middleware('auth');
}
//
public function index() {
// TODO Gets Data...
$datos = ['Nombre', 'Otro Nombre', 'Otro mas'];
// Return Data to tyhe view...
if(Auth::user()->roles == '11') {
return View('admin.home', compact('datos'));
} else {
return View('/welcome');
}
}
}
And thats how you get different views based on users information... at least is working for me..
------------Update
After I play a little bit with this, I find out that that even when you load the correct view for admin / user / customer / providers...etc the url/path is not correct here is why:
with the code above you get foo.com/login when user loads the Delegation Controller which serves the correct view but the url stays as foo.com/delegate if the user is an admin we want something like foo.com/admin not /delegate and even if you change it manually from /delegate to /admin it still work, but here is the problem because if the user is not an admin it will still shows the admin panel and we don't want that... to fix that I had to change my delegation controller... instead of loading a view I have to redirect the user to a correct path...
public function index() {
if(Auth::user()->roles == '10') {
return redirect()->route('admin');
} else {
return redirect()->route('/');
}
}
this isthe same code as before but instead of loading a view I redirect the user, in order for this to work properly in your routes file you have to declare each the name of each path as follow
Route::group(['middleware' => ['web']], function () {
Route::auth();
Route::get('delegate', 'DelegateController#index');
// Add your route
// Route::get('admin', 'AdminController#home');
Route::get('admin', ['as'=>'admin', 'uses'=>'AdminController#home']);
});
That way you can redirect your user to any part of your site by calling the names route return redirect()->route('/myprofile') ...etc
Now that this is working we need to do one last check as to what user is loading what, to do that is very simple on each of your view controllers you should have something like this...
class AdminController extends Controller
{
public function __construct()
{
$this->middleware('auth');
// gets the disco bouncer working...
if(Auth::user()->roles != '10') {
Auth::logout();
}
}
//
public function home() {
// TODO Gets Data...
$datos = ['Nombre', 'Otro Nombre', 'Otro mas'];
// TODO build a model for the actual data...
// Return Data to the view...
return View('admin.home', compact('datos'));
}
}
As you can see we can use this on all Controllers and skip the DelegationController but then you going to have to do a menu for each user role on a single app.blade master view which will look a lot more dirty...
If you ask me, yes I'm having fun learning Laravel!