laravel controller cannot use currentRouteName() inside construce() - laravel

I have named routes:
admin.post.category
admin.post.tag
admin.post.theme
routes\admin.php
Route::group(['prefix' => 'post', 'as' => 'post.'], function () {
Route::resource('category', 'Admin\Post\TermsController');
Route::resource('theme', 'Admin\Post\TermsController');
Route::resource('tag', 'Admin\Post\TermsController');
});
Http\Controller\Admin\Post\TermsController
public function __construct(Request $request)
{
$this->request = $request;
$route_name = Route::currentRouteName();
$arr = explode('.', $route_name);
echo "<pre>".print_r($arr[2], 1)."</pre>"; exit;
}
When I visit the page http://localhost/admin/post/category, it can show category. But when I run command
php artisan route:list
It shows
[ErrorException]
Undefined offset: 2
If I move the three lines from __construct() to index()
$route_name = Route::currentRouteName();
$arr = explode('.', $route_name);
echo "<pre>".print_r($arr[2], 1)."</pre>"; exit;
Then "php artisan route:list" runs well.
How to fix this?

It's throwing the error because you have some routes with names that contain only 1 dot. So when you access $arr[2] it's undefined and thus the error Undefined offset: 2. Looks like your shoving every route method into a single controller. When you try to run php artisan route:list it checks every route, thereby invoking the constructor, so it fails for routes with names with just 1 dot. Change your code to this and it should work.
$route_name = \Route::currentRouteName();
$arr = explode('.', $route_name);
if (isset($arr[2])) {
echo "<pre>".print_r($arr[2], 1)."</pre>";
}
exit;

Related

Laravel - Status Code: 500 Internal Server Error

hello i want to update my data in DB using V-form but 500 internal server error show:
this is my function in controller:
public function update(Request $request, $id)
{ $data =$request->all();
//
$client = Client::where('id', $data['client_id'])->first();
DB::table('projets')->where('id',$id)->update(['name'=>$data['name'],'durre'=>$data['durre'],'description'=>$data['description'],'owner'=>$client->name,'budget'=>$data['budget']]);
}
and this is my route:
Route::apiResource('projet' ,'API\ProjetController');
and this is the vue code:
modifier(){
this.form.put('api/projet/'+ this.form.id).then(function(){
$('#AjouterProjet').modal('hide')
seww.fire(
'Modifier!',
'Your User has been Updated.',
'success'
)
fire.$emit('ajoutprojet');
}).catch(function(){
})
},
In your route specify the Controller function to execute like this
Route::apiResource('projet' ,'API\ProjetController#update');
When you get 500 error, Check the last file on storage/logs directory and try to find the last error on this file, errors are in this format:
[date_time] [error_message] [stacktrace]

Laravel Routing Query

I've made some bespoke pages in my admin of my site and they as the first segment of the URL.
e.g
/property-hartlepool
I thought of adding a trap all route into my routes file :
Route::get('{any?}', 'PagesController#view');
The problem I have is it's totally overwriting my other routes, I guess that's the name of a trap all route. However I'd like it to skip if it can't find a match.
I had a route for admin
/admin
But now it throws a 404 Error...
My PagesController#view method is :
public function view(Request $request)
{
$route = $request->segment(1); // $request->path();
// get page content
$page = Page::where('route', $route)->firstOrFail();
// If not full width, get four latest properties
//$properties = Property::latest_properties_for_frontend();
//metadata
$meta = get_metadata($page);
//page is Temporary
return view('frontend.'.themeOptions().'.page', [
'route' => $route,
'meta' => $meta,
'page' => $page
]);
}
Is their a better way of doing this, I do have other routes that sit at "top" level too. e.g...
Route::get('/property/{property}/{propertyId}', 'PropertiesController#property');
declare your trap Route as the last route.
Route::get('/admin', 'AdminController#view');
...
...
Route::get('{any?}', 'PagesController#view');

Laravel Closure Request

Assalamualaikum guys, i have some problems with my code. i tried to make search by using request parameters on laravel. and here is my code views.
$maintenance->with([
'user_post' => function($query, Request $request){
if($request->has('searchBy') && $request->has('searchQuery'))
{
$parse_query = explode('.',$request->query('searchBy'));
$is_user = $parse_query[0] == 'user_post'? true : false;
if($is_user)
{
$query->where($parse_query[1],'LIKE','%'.$request->query('searchQuery').'%');
}
}
},
'dt_project'
]);
when i tried to execute on browser, it return
1/1) ErrorException
Undefined variable: request
what should i do? thanks to the moon and back. hehehe
try this, change your line 2 to:
'user_post' => function($query) use($request){
explanation:
Request $request can only be used in controller functions like:
public function store(Request $request)
{
//code here
}
in order to pass the $request parameter inside another function, use use (this is also known as variable inheriting):
public function store(Request $request)
{
$user= User::with(['roles' => function($query) use($request){
^^^
$query->where('roles.id', $request['role_id'])->first();
}])->get();
}

Laravel routes: subfolders and error in RouteCollection

I have urls with subfolders:
/book/yur.voprosy/vopros-1.json
I don't count of subfolders levels which will be after /book/
My route is:
Route::get('/book/{file?}', 'BookController#index');
But if levels are more then 1 laravel returns:
NotFoundHttpException in RouteCollection.php line 161:
How to fix it?
You cannot really do that in Laravel, because the routing system expects you to define the exact "path", so, for it to work, you would have to:
Route::get('/book/{folder?}/{file?}', 'BookController#index');
Use it in your controller this way:
public function index($folder = null, $file = null) { ... }
So you can then do
Route::get('/book/{f1?}/{f2?}/{f3?}/{f4?}/{f5?}/{f6?}/{f7?}', 'BookController#index');
And in your controller use
public function index() {
$file = implode('/', func_get_args());
}
$numargs = func_num_args();
Or you can do:
Route::get('/findbook', 'BookController#index');
Then hit
https://yourdomain.com/findbook?filename=yur.voprosy/vopros-1.json
And get it within your controller using
Input::get('filename')

How to call function in __constructor using laravel 5?

I am fetching menus from database based on user rights and displaying it to my web page but if i access any url whose access i don't have then too it opens that page.
For this i have created and called access_denied function which redirect user's home page.
I have called access_denied function from constructor of AuthController because AuthController gets loaded on each page.
I have used following code
AuthController
public function __construct()
{
$this->accessDenied();
}
public function accessDenied()
{
$url_segment1 = Request::segment(1);
$url_segment2 = Request::segment(2);
$url_segment = $url_segment1 . '/' . $url_segment2;
$user_data = Auth::user()->toArray();
$dadmin = array_keys($user_data['admin']);
//this is sample of array
// $user_data['admin'] => Array
// (
// [admin/roles] => 1
// )
if (!in_array($url_segment, $dadmin)) {
return redirect('/home');
}
}
But I am getting following error
Non-static method Illuminate\Http\Request::segment() should not be called statically, assuming $this from incompatible context
If i using incorrect process then please suggest me correct way to redirect unauthorised user on home page.
First, you should create a middleware. In a command prompt type:
php artisan make:middleware AccessDenyMiddleware
Then you go to app/Http/Middleware/AccessDenyMiddleware.php and fill in the handle function {your own code}
$url_segment1 = Request::segment(1);
$url_segment2 = Request::segment(2);
$url_segment = $url_segment1 . '/' . $url_segment2;
$user_data = Auth::user()->toArray();
$dadmin = array_keys($user_data['admin']);
//this is sample of array
// $user_data['admin'] => Array
// (
// [admin/roles] => 1
// )
if (!in_array($url_segment, $dadmin)) {
return redirect('/home');
}
But add the following line
return $next($request); // If passed, proceed with the route
Then, in a route, you should type:
Route::get('/yoururlhere', ['middleware' => 'AccessDenyMiddleware', function() { /* Put your work here */ } ]);
There are much better approaches. Like Authorisation if you are using Laravel 5.2
Or maybe change the default Authenticate middleware if you are using Laravel 5
You can use a middleware for thath https://laravel.com/docs/5.2/middleware#introduction.
php artisan make:middleware RoleRouteMiddleware
You should put thath code in the handle method of the middleware "App\Http\Middleware\RoleRouteMiddleware" and use the $request variable instead of the facade Request.
The middleware would filter earch request to your app.
Register a middleware, add it on app/Http/Kernel.php at routeMiddleware array
protected $routeMiddleware = [
....
'alias' => App\Http\Middleware\RoleRouteMiddleware::class,
];
and then use it on specific routes like this:
Route::get('admin/profile', ['middleware' => 'alias', function () {
//your code here
}]);
or in route gruoups:
Route::group(['middleware' => 'alias', function () {
//your filtered routes
}]);

Resources