Extending Laravel's Validator Class - laravel

I am using the Laravel's validator class, and when validation fails I print out the errors with this method:
$validator->messages();
The method returns a multi dimensional array, I need a single dimensional array.
$validator->net_method();
How will I go about extending a new method to return the errors in a different format?

Related

Laravel's Accessor call only when requested [duplicate]

Is there any possible way to lazy load a custom attribute on a Laravel model without loading it every time by using the appends property? I am looking for something akin to way that you can lazy load Eloquent relationships.
For instance, given this accessor method on a model:
public function getFooAttribute(){
return 'bar';
}
I would love to be able to do something like this:
$model = MyModel::all();
$model->loadAttribute('foo');
This question is not the same thing as Add a custom attribute to a Laravel / Eloquent model on load? because that wants to load a custom attribute on every model load - I am looking to lazy load the attribute only when specified.
I suppose I could assign a property to the model instance with the same name as the custom attribute, but this has the performance downside of calling the accessor method twice, might have unintended side effects if that accessor affects class properties, and just feels dirty.
$model = MyModel::all();
$model->foo = $model->foo;
Does anyone have a better way of handling this?
Is this for serialization? You could use the append() method on the Model instance:
$model = MyModel::all();
$model->append('foo');
The append method can also take an array as a parameter.
Something like this should work...
public function loadAttribute($name) {
$method = sprintf('get%sAttribute', ucwords($name));
$this->attributes[$name] = $this->$method();
}

Validate when fields depend on one another

I am passing a request object name Person to controller. Lets say the object has 2 two fields. The following business rule apply:
If field age has a value < 18, the field sin should be left blank;
If not, it will produce exception with message the sin should be blank with age < 18 or another way is to set the field sin to empty string("").
What is the best way for me to validate those inputs when they depend on each other. My way to deal with them is to validate them inside the controller method. So it should look something like that
#GetMapping("/..."
public ResponseEntity<PersonResponse> getPersonResult(GetPersonRequest request)
{
if (request.getAge() < 18)
{
if (request.getSin.length > 0)
request.setSin("")
}
PersonResponse response = callThirdPartyAPIToRetrieveInformationAboutThatPerson(request)
return response ;
}
Is there any more elegant way to code ? Is it ok for the controller method to contain any validation logic like that ? am i violating the Single Responsibility in SOLID design ?
Yes, of course! And this is a good approach: single responsibility of classes - a controller is responsible for handling data, validator - for validation of data; open-closed principle - validated data is unchangeable by controller's method; Liskov principle correlates with the base OOP principles - a validator is separated entity and can be changed to another one without any additional manipulations; Interface Segregation is clear without any description (fully separated classes); Depency Inversion is also understandable - using annotation interface, controller does not know anything about its implementation. So, it's a really good approach from ideology and language syntax.
Implementation.
Create class-level #interface. All fields are accessible.
Create ConstraintValidator class with validation logic.
Set this annotation for #RequestBody in the controller method.
Add validation functionality for controller: #Validated for controller class and #Valid for #RequestBody entity in controller method.
If you need to handle validation exceptions, just throw a new exception and handle it in #ControllerAdvise class, no handling code in validation or controller classes.
Example of creation class-level validator in the official resource.

Lumen 5.3: How to extend validation class

Validation class has a couple of functions to retrieve errors, how can I extend this class to manipulate array structure of error messages:
$v = Validatior::make($input, $rules);
if($v->fails()){
// Instead of
print_r($v->errors()->messages());
// Have
print_r($v->getErrorsWithMyPreferedStructure());
}
I want to add my own function to validation class. Obviousely one of the possible solutions is extending validation class and ... But it's not what I'm searching for. I'm looking for a way to extend validation class via it's own methods, if any!

Laravel overwrite toArray with custom parameter

In my controller I have:
$Locations = Locations::where(something);
$Locations->get()->toArray(true);
And inside the model:
function toArray($include_all = false) {
var_dump($include_all);
}
The include all variable is false, although the function gets called.
Is there a reason why it's doing that ?
I want to call a custom toArray because I have more oneToMany relations with different structures that I want to change (some of them are serialized for example)
Thank you
You can use Illuminate\Support\Collection methods such as map() and filter() to modify the collection and at the end of that call toArray() method.
It would be fairly easy to overwrite, however I think there is some confusion that should be cleared up first.
First, the toArray() method you are calling in this case is on the Collection which is the object which is returned when you use get() on your model.
With that said, you can add the following to your Location model to return a custom collection...
public function newCollection(array $models = [])
{
return new CustomCollection($models);
}
Then you write the new CustomCollection class with appropriate namespaces just to make sure it gets auto loaded fine, have it extend \Illuminate\Database\Eloquent\Collection and then you can proceed to override the toArray method.
However, it feels like you randomly selected this toArray() as a proper candidate to perform your logic just because you are already using it. You should think about creating a new function which calls $this->toArray() to grab the results and modify them as you need and return that.
If you need this same functionality on other models, just keep adding that newCollection method where needed.
This is also in the docs as well, might be worth checking out...
https://laravel.com/docs/5.2/eloquent-collections#custom-collections

How add in the view one method using entities

I am studying the framework entities and need to add a method in the #view.
This is My code:
#Views({
#View(
name="CreatClient",
title="Cliente",
members="#Codigo;#nome;#Telefone;#Endereco",
rows=10)
});
You need add the method name after of endereco in members...
;methodname()
And make the method in the class

Resources