I see that laravel controller comes with 2 request class. Are they the same?
use Illuminate\Http\Request;
and
use App\Http\Requests;
Is it optional to choose one over the other?
use Illuminate\Http\Request;
This one is a file located in vendor/laravel/framework/src/Illuminate/Http/Request.php , it's a class with all the methods and properties related to a request, it extends SymfonyRequest.
class Request extends SymfonyRequest implements Arrayable, ArrayAccess
{
// ...
}
use App\Http\Requests;
This one itself is just a namespace, it's like a stub to the requests namespace. I never use it (I use a line for every request).
It could be used in this way:
public function save(Requests\FormRequest $request)
App\Http\Requests\Request extends the Illuminate\Foundation\Http\FormRequest and any class that extends it is going to validate itself when resolved out of the IoC Container.
On the other hand Illuminate\Http\Request is just a plain request that extends directly from SymfonyRequest it's useful to inject in your controller methods if you just need to extract the request parameters or the user from the current request.
Laravel 5 (I hope :p) you can just use at the top:
use Request;
I am not much sure about use Illuminate\Http\Request;
But App\Http\Request is the class which is used to:
Get users' input data.
If user fills form, then we can get data with the help of this class.
2.Make user input validations.
Validations can be done in controller but it is not good practice.
We should use seperate request class that can be made by:
php artisan make:request request-class-name.
This will make a file in App\Http\Requests\ with given name i.e. request-class-name.
In this class we can do validations as well as authorizations.
If you want to learn about authorizations then learn about Gates https://laravel.com/docs/5.4/authorization.
Related
I am working on a spring base web application where, we have a few RestControllers and some Request DTO classes. Request DTO contains a token field which needs some validation. So I used spring validators to validate that. After validation, we want to send that field to an external system using another REST API (Just for some kind of analytics logging). The same field is repeated in multiple DTO objects and their controllers. So, I am easily able to define annotations for validators and reuse them across the DTOs. But I am not sure how to process that field after validation succeeds (i.e. call analytics API to consume that field post validation), without mixing it with the core logic of controllers.
Approaches I could think of:
Implement a filter/interceptor and process the field there. But then
there is a limitation that request body can be read only once so I
need to use some alternate ways by creating request wrappers.
Repeat the logic in every controller and it is very error prone as for
every new controller we need to remember to write that code.
But non of these approaches look cleaner. Can someone recommend a better way to achieve that?
Thanks in advance.
You can create a BaseController and implement the method there. Extend this BaseController wherever you need this logging service. Like below.
BaseController.java
class BaseController {
protected void remoteLogging(String name,String token) {
//Calling the remote log services}
}
AppController.java
#Controller
#RequestMapping("register")
public class LeaseController extends BaseController {
#PostMapping("new")
public String new(#Valid #ModelAttribute("registration") Registration registration,BindingResult result){
if(rest.hasErrors(){
remoteLogging("name","token");
}
}
I will give an analogy to explain what I want:
For example, if I want to read about the "behaviour" of the save() method in:
$model->save();
then I can go to Illuminate\Database\Eloquent\Model
to read what's inside
public function save() {....}
QUESTION: If I want to know the behaviour of extend() in
Validator::extend('','');
Where in the system laravel files should I go?
Thank you in advance!:)
Facades are a bit harder to find than other classes, since they only reference a service container binding. You'd have to find the class where this binding is registered to find the backing class.
The easiest way, for official facades, is to just check the Facades Documentation, there is a list of facades and their backing classes at the bottom:
Validator Illuminate\Validation\Factory validator
So the Validator facade resolves to the class Illuminate\Validation\Factory which is bound to the service container with the name validator. From here on, it should be easy to find the Illuminate\Validation\Factory class in your vendor directory.
Out of the box, laravel 5.2 comes with a couple of ORM classes. Most notably, one of these is the User ORM class. Most ORM models, must extend Illuminate\Database\Eloquent\Model, which looks something like this:
use Illuminate\Database\Eloquent\Model;
class Articles extends Model {
...
However, the user model must extend Illuminate\Foundation\Auth\User, if you want to use any of the authentication features. This is typically seen as something like the following:
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable {
...
However, all of my ORM files extend a custom ORM class, (which contains some default query scoping methods and other very useful things I've written) which then, in turn extends Illuminate\Database\Eloquent\Model.
So in other words, I want to have:
Illuminate\Database\Eloquent\Model
App\Klass\OrmRoot\MyCoolSubClass extends Illuminate\Database\Eloquent\Model
App\Klass\Orm\User extends MyCoolSubClass
But I'm forced to have:
Illuminate\Database\Eloquent\Model
App\Klass\OrmRoot\MyCoolSubClass extends Illuminate\Database\Eloquent\Model
App\Klass\Orm\User extends Illuminate\Foundation\Auth\User
As PHP doesn't support polymorhpic inheritance, when stating which class my User.php ORM file extends from, I have to choose between either duplicating all the methods I have in my custom base ORM class inside the User ORM class (ridiculous), or not having the user ORM class have user authentication functionality. Both seem unfeasible.
Is there any other way to include the Authenticable functionality in a User.php ORM file? Perhaps as a trait? There doesn't seem to be any documentation regarding this usage pattern.
Ok, just figured it out.
Checking the content of Illuminate\Foundation\Auth\User, revealed it to contain only the following:
namespace Illuminate\Foundation\Auth;
use Illuminate\Auth\Authenticatable;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Auth\Passwords\CanResetPassword;
use Illuminate\Foundation\Auth\Access\Authorizable;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Contracts\Auth\Access\Authorizable as AuthorizableContract;
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;
class User extends Model implements
AuthenticatableContract,
AuthorizableContract,
CanResetPasswordContract
{
use Authenticatable, Authorizable, CanResetPassword;
}
Having my User.php ORM file extend my custom class "MyCoolSubClass", and ensuring that it also implements all traits and contracts shown above achieves the desired result of being able to use the features of my custom ORM base class along with the auth features.
I need to extend Illuminate\Support\MessageBag because of add some help methods but I cant bind my own class App\Support\MyMessageBag to laravel use my class (that extends App\Support\MyMessageBag) instead of original core class.
Do you have any ideas?
I was wondering if it's somehow possible to add another abstraction controller between AppController and my app's other controllers?
So that my controllers, e.g. UsersController extends SecureController
and SecureController extends AppController.
Also I want to be able to have other controllers extend AppController directly:
SomeNonSecureController extends AppController.
this is because my current AppController has all sorts of Auth and ACL stuff in its beforeFilter, but i also have controllers that don't need that security stuff (before everything needed the security, no new specs have been added)..
but because some many controllers do need it, it doesn't make sense to copy-paste the code to all needy controllers.
I was thinking to but all the beforeFilter security stuff into a SecureController - that way any controllers that need security simpley extend it, while others inherit from AppController directly.
How would you go on about doing something like this?
Thanks in advance,
Ken.
My first thoughts would be to see if I could abstract some of the functionality from the beforeFilter into a component - remember components can use other components too, just include them in your component's $components property, so you can access the AuthComponent and AclComponent etc.
If this was not suitable then I'd go for your route, in order to do it, just include('secure_controller.php'); before your individual controller class declaration in it's file.
I have done something similar by creating a BaseController that I use in all my projects which provides all my admin CRUD actions that are standard. I then have my AppController extend this which contains application specific, controller wide functionality, then individual controllers extend that, and end up being practically empty. All I do is:
// app/base_controller.php
<?php class BaseController extends Controller {} ?>
// app/app_controller.php
<?php
include('base_controller.php');
class AppController extends BaseController {}
?>
// app/controllers/my_controller.php
<?php class MyController extends AppController {} ?>
I've just been attempting this too. It seems it's relatively simple to extend any controller with any other one. In Cake 2.0 you just use the import() statement (include() does a similar thing).
App::import('Controller', 'Security');
class SecureAreaController extends SecurityController {
// extra functionality *not* in base class goes here
}