I would like to keep my authorization as DRY as possibile.
Currently for my update method I am using Laravel 5 FormRequest.
Example:
/**
* Determine if the user is authorized to make this request.
*
* #return bool
*/
public function authorize()
{
$commentId = $this->route('comment');
return Comment::where('id', $commentId)
->where('user_id', Auth::id())->exists();
}
The problem is that this gets triggered just for update method:
/**
* Update the specified resource in storage.
*
* #param int $id
* #return Response
*/
public function update(UpdateRequest $request, $id)
{
// ...
}
How can I use the same authorize logic for edit method?
Otherwise everyone can just type:
/resources/ID/edit
^
not allowed
Only the owner should see that page, not everyone
Note I can't add that same UpdateForm to the edit method, because otherwise validation could be triggered too
/**
* Show edit form for the specified resource in storage.
*
* #param int $id
* #return Response
*/
public function edit(UpdateRequest $request, $id)
{
// ...
}
You have something called middleware in laravel 5.
You can use it in the route so that it gets executed before the action has been called.
I think for what you need you will have to create your own middleware.
http://laravel.com/docs/master/middleware
After you created one you have to tell laravel to use the middleware and then add it to your route like so
route::get('test', ['middleware' => 'yourmiddleware', 'uses' => 'yourController#index']);
Related
Im having some trouble with Laravel policies and cant work out why this isnt working?
I have a policy attached to a model with all the regular methods (index, create, show etc)
The index page is working fine, but i keep getting a 403 page not found when going to the view page?
As you can see in the policy i have returned true whether the check is succesfull or not and it still returns a 403
ShippingController
/**
* Display the specified resource.
*
* #param int $id
* #param ShippingModel $shippingModel
* #return \Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View|\Illuminate\View\View
* #throws \Illuminate\Auth\Access\AuthorizationException
*/
public function show($id, ShippingModel $shippingModel)
{
$this->authorize('view', ShippingModel::class);
return view('pages.warehouse.shipping.show');
}
ShippingModelPolicy
/**
* Determine whether the user can view the model.
*
* #param \App\Models\User $user
* #param \App\Models\ShippingModel $shippingModel
* #return \Illuminate\Auth\Access\Response|bool
*/
public function view(User $user, ShippingModel $shippingModel)
{
if ($user->isSuperAdmin() || $user->hasPermissionTo(205, 'web')) {
return true;
}
return true;
}
I have added the authorize in the method even though i have the authorizeController defined as well but it still does not work
public function __construct()
{
$this->authorizeResource(ShippingModel::class, 'shippingModel');
}
Your view policy method is dependent on a model, but the check on the controller doesn't account for a model. Delete the second argument and only leave User $user
I am using laravel 5.5 and I am trying to use a automatic route to the controller but it isn't working
In the web.php(the routing file for this version)
I have the follow line
Route::resource('panel', 'panel');
Route::resource('/', 'HomeController');
In the panel I have the follow actions
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
class panel extends Controller{
public function index(){
return \View::make('panel.index');
}
public function registrar(){
return \View::make('panel.registrar');
}
}
but it's only calling the index() view
the registrar() view is not being called when user acess the url
site.com/panel/registrar
the follow erro is printing in the screen
"Method [show] does not exist on [App\Http\Controllers\panel]."
I tried to use the base_controller but it don't work too
"Class 'App\Http\Controllers\Base_Controller' not found"
is there an way to identify these actions ?
Resource routing sets up 7 specific routes, that is 7 specific methods you need on the controller, 7. If you dont want all 7 of those routes you have to define it that way.
Resource routing is not implicit controllers. It does not look at the method on the controller then make routes .. Resource routing is a 'specific' thing. We do not have implicit controllers any more in Laravel as there is really no point.
Laravel 5.5 Docs - Controllers - Resource Controllers
You have routes that are created that point to methods that don't exist, that is what the error is.
Also, the first argument to Route::resource is a resource 'name', not a PATH. It is not technically a URI. It is a name of a resource.
Route::resource('/', ...) // not a name
This is a resource controller with basic CRUD operations, so in order to work you have to define the rest methods like in your case you should add a method show() and then render the view you want in that method.
A resource controller must have the following methods defined:
class TestController extends Controller
{
/**
* Display a listing of the resource.
*
* #return \Illuminate\Http\Response
*/
public function index()
{
//
}
/**
* Show the form for creating a new resource.
*
* #return \Illuminate\Http\Response
*/
public function create()
{
//
}
/**
* Store a newly created resource in storage.
*
* #param \Illuminate\Http\Request $request
* #return \Illuminate\Http\Response
*/
public function store(Request $request)
{
//
}
/**
* Display the specified resource.
*
* #param int $id
* #return \Illuminate\Http\Response
*/
public function show($id)
{
//
}
/**
* Show the form for editing the specified resource.
*
* #param int $id
* #return \Illuminate\Http\Response
*/
public function edit($id)
{
//
}
/**
* Update the specified resource in storage.
*
* #param \Illuminate\Http\Request $request
* #param int $id
* #return \Illuminate\Http\Response
*/
public function update(Request $request, $id)
{
//
}
/**
* Remove the specified resource from storage.
*
* #param int $id
* #return \Illuminate\Http\Response
*/
public function destroy($id)
{
//
}
}
And base controller obviusly it is not Base_Controller but its Controller
For more please reffer here Laravel 5.5 Resource Controllers
Change this resourse to simple get , if you don't need all resource methods
Route::get('/panel', 'panel#index');
Route::get('/panel/registrar', 'panel#registrar');
And use home instead just / to get unconflicted url
Route::resource('home', 'HomeController');
I get the error when trying to make a post call to /api/subject/search
I assume it's a simple syntax error I'm missing
I have my api routes defined below
Route::group(array('prefix' => 'api'), function()
{
Route::post('resource/search', 'ResourceController');
Route::resource('resource', 'ResourceController');
Route::post('subject/search', 'SubjectController');
Route::resource('subject', 'SubjectController');
Route::resource('user', 'UserController');
Route::controller('/session', 'SessionController');
Route::post('/login', array('as' => 'session', 'uses' => 'SessionController#Store'));
});
And my controller is mostly empty
class SubjectController extends \BaseController
{
public function search()
{
$subjects = [];
if((int)Input::get('grade_id') < 13 && (int)Input::get('grade_id') > 8)
$subjects = Subject::where('name', 'like', '%HS%')->get();
else
$subjects = Subject::where('name', 'not like', '%HS%')->get();
return Response::json([
'success' => true,
'subjects' => $subjects->toArray()
]);
}
/**
* Display a listing of the resource.
*
* #return Response
*/
public function index()
{
//
}
/**
* Show the form for creating a new resource.
*
* #return Response
*/
public function create()
{
//
}
/**
* Store a newly created resource in storage.
*
* #return Response
*/
public function store()
{
//
}
/**
* Display the specified resource.
*
* #param int $id
* #return Response
*/
public function show($id)
{
//
}
/**
* Show the form for editing the specified resource.
*
* #param int $id
* #return Response
*/
public function edit($id)
{
//
}
/**
* Update the specified resource in storage.
*
* #param int $id
* #return Response
*/
public function update($id)
{
//
}
/**
* Remove the specified resource from storage.
*
* #param int $id
* #return Response
*/
public function destroy($id)
{
//
}
}
You need to specify the method.
try
Route::post('subject/search', 'SubjectController#search');
See the named route example:
Laravel Docs
In your case I think search is not resolved by the controller to load the search() method. You are also sending a POST for search functionality and I guess it's better to do a GET request since POST and PUT are for storing data.
Conventions
When creating API's it's a good thing to stick to naming conventions and patterns.
http://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api
Solution
Your route could be simpler like this: api.yourdomain.com/api/subject?search=term1,term2. Doing this with a GET query makes it going to the index() method. There you can check the GET params and do your search stuff and return.
Check this for the cleanest and truely RESTful way to make an API in Laravel:
How do I create a RESTful API in Laravel to use in my BackboneJS app
I got same error when accessing object at index of an empty array in view blade php file.
I have a RESTful controller for my users to handle the viewing of a users profile.
The problem is this:
I want the url to look like this www.example.com/user/1
This would show the user with the id of 1. The problem is that when i define the getIndex method in the UserController it wont accept the id as an argument.
Here is my routes.php portion:
Route::controller('user', 'UserController');
Now, it is my understanding that getIndex is sort of the default route if nothing else is supplied in the url, and so this:
public function getIndex() {
}
within the UserController will accept routes,
"www.example.com/user/index"
and
"www.example.com/user"
and it does!
However, if I include an argument that it should take from the url, it no longer works:
public function getIndex($id) {
//retrieve user info for user with $id
}
This will only respond to
"www.example.com/user/index/1"
and not
"www.example.com/user/1"
How can i make the latter work? I really do not want to clutter up the url with the word "index" if it is not necessary.
If you are planning to do this, the best way is to use RESTful controllers.
Change your route to this one,
Route::resource('user', 'UserController');
Then generate a controller using php artisan command,
php artisan controller:make UserController
This will generate your controller with all RESTful functions,
<?php
class UserController extends \BaseController {
/**
* Display a listing of the resource.
*
* #return Response
*/
public function index() // url - GET /user (see all users)
{
//
}
/**
* Show the form for creating a new resource.
*
* #return Response
*/
public function create()
{
//
}
/**
* Store a newly created resource in storage.
*
* #return Response
*/
public function store() // url - POST /user (save new user)
{
//
}
/**
* Display the specified resource.
*
* #param int $id
* #return Response
*/
public function show($id) // url - GET /user/1 (edit the specific user)
{
//
}
/**
* Show the form for editing the specified resource.
*
* #param int $id
* #return Response
*/
public function edit($id)
{
//
}
/**
* Update the specified resource in storage.
*
* #param int $id
* #return Response
*/
public function update($id) // url - PUT /user/1 (update specific user)
{
//
}
/**
* Remove the specified resource from storage.
*
* #param int $id
* #return Response
*/
public function destroy($id) // url - DELETE /user/1 (delete specific user)
{
//
}
}
For more info, see this one Laravel RESTful controller parameters
To display www.example.com/user/1 on address bar you should use show method. In Laravel, restful controller by default create 7 routes. Show is one of them.
in your controller create a method like the following:
public function show($id)
{
// do something with id
$user = User::find($id);
dd($user);
}
Now, Browse http://example.com/user/1.
I am trying to make the laravel 4 controller in mac terminal by
php artisan controller:make UserController
It work's and insert the controller in the folder.
In my route.php i add:
Route::controller('users', 'UserController');
In my UserController in index i make
return "Hello world"
But when i am entering localhost/users it don't show anything, either in /users/create.
What can i do?
Trace errors:
Symfony \ Component \ HttpKernel \ Exception \ NotFoundHttpException
open: /Applications/XAMPP/xamppfiles/htdocs/salety/laravel/vendor/laravel/framework/src/Illuminate/Routing/Router.php
* #param Exception $e
* #return void
*/
protected function handleRoutingException(\Exception $e)
{
if ($e instanceof ResourceNotFoundException)
{
throw new NotFoundHttpException($e->getMessage());
}
UserController
<?php
class UserController extends \BaseController {
/**
* Display a listing of the resource.
*
* #return Response
*/
public function index()
{
return "Hello world!";
}
/**
* Show the form for creating a new resource.
*
* #return Response
*/
public function create()
{
//
}
/**
* Store a newly created resource in storage.
*
* #return Response
*/
public function store()
{
//
}
/**
* Display the specified resource.
*
* #param int $id
* #return Response
*/
public function show($id)
{
//
}
/**
* Show the form for editing the specified resource.
*
* #param int $id
* #return Response
*/
public function edit($id)
{
//
}
/**
* Update the specified resource in storage.
*
* #param int $id
* #return Response
*/
public function update($id)
{
//
}
/**
* Remove the specified resource from storage.
*
* #param int $id
* #return Response
*/
public function destroy($id)
{
//
}
}
You need to change Index to getIndex when using RESTful controllers.
What you've created using the artisan command is a resource controller.
To get this to work, change your routes.php file to this:
Route::resource('users', 'UserController');
This will make the /users route a resource and allow it to respond properly.
Be sure to look at the documentation on resource controllers and be sure to pay attention to the Actions Handled By Resource Controller section, as this gives you the key to what methods are used for which URI's.
Well for restfull controllers you need to use this form getIndex , getCreate , postRegister..etc , you can either use Route::controller() or Route::resource()
after changing stuff in your routes.php you need to run
php composer dump-autoload
to refresh the autoloading files with edited routes.