Validating Multiselect CakePHP 3 belongsToMany Entites - php

I'm want to ensure that a multi-select field (belongsToMany) has at least one item checked/selected. I have two entities:
Listings and PaymentTypes - belongsToMany.
My field is created with the helper:
echo $this->Form->input('payment_types._ids', ['options' => $paymentTypes, 'multiple' => 'checkbox']);
In my ListingsModel.php file I have my validator setup as follows:
public function validationDefault(Validator $validator) {
$validator = new Validator();
$validator->requirePresence('payment_types._ids');
return $validator;
}
This prevent the save from happening but I don't see any validation error message. Why doesn't the HTML5 form validation work as it does on other fields which are of type text?

I managed it with this custom rule:
->add('delivery_types', [
'multiple'=>[
'rule'=>['multiple', ['min'=>1]],
'message'=>'Select at least one method of delivery method'
]
])
This isn't especially well documented in the book so hopefully it iwll be of some help to others starting with Cake v.3

You should be able to accomplish this with nested validators - http://book.cakephp.org/3.0/en/core-libraries/validation.html#nesting-validators.
As an example:
public function validationDefault(Validator $validator) {
$paymentTypesValidator = new Validator();
$paymentTypesValidator->requirePresence('_ids');
$validator-> addNested('payment_types', $paymentTypesValidator);
return $validator;
}
You could then decorate the $paymentTypesValidator object with any other rules you require.

Related

Laravel 5.5 validating hasMany relationship

How can I create a validation on a hasMany relationship
That is my Product model
public function produtoAtributos(){
return $this->hasMany("App\ProdutoAtributo", "produto_id", 'id')->latest();
}
and in Controller I fill the inputs than save it
$produtoatributos = $model->produtoAtributos()->getModel();
$produtoatributos->tipo = $produtoAtributo['tipo'];
$model->produtoAtributos()->save($produtoatributos);
The form input looks like this
<input name="ProdutoAtributos[0]['tipo']" />
How can add a validation for the relationship?
Laravel provide a nice way to validate arrays inpputs.
Here is an example
$validator = Validator::make($request->all(), [
'ProdutoAtributos.*.tipo' => 'required',
]);
You can read more about it here
https://laravel.com/docs/5.6/validation#validating-arrays

When validating data in Laravel 5.5, Update returns "unknown column in field list" error where Create does not

Laravel 5.5 introduces a new streamlined request validation. The idea being that:
$validData = $request->validate($rules)
will return only those fields that are present in the $rules. This is beneficial so that one can then simply User::create($validData) or User::update($validData).
However, I noticed that when I have additional data, which I do validate, but that doesn't exist in the model's (this case User) table, the create method inserts the record, but that the update method returns this error:
Column not found: 1054 Unknown column 'column_name' in 'field list'
I can of course write the relevant field lists out, or use other workaround, but I wonder why are the two methods are behaving differently?
e.g. passing
array:4 [▼
"first_name" => "Pedro"
"last_name" => "Taco"
"email" => "taco#example.org"
"operators" => array:1 [▼
0 => "1"
]
]
to User::create() inserts the record. Passing the same to User::update() returns an error.
User has $fillable = 'first_name', 'last_name', 'email'
I believe they behave the same but in update method you have some extra fields that are not in table in database, so you should verify what exactly you send and what exactly you validate to make sure there are no additional fields in $validData when you are updating user.
If you think that's not the case, please show us exactly how the validation looks like for creating and updating user.
If you want to update specific data use where
User::where('id',1)->update($validData);
If you want to update all rows try something like this
User::where('id','!=',-1)->update($validData);
OR
User::query()->update($validData);
If you are trying to use validations, you can decouple the code even further using Request validations.
Here you have a full example of applying Request validations and extracting just the necessary data to store (or update) objects:
1. Generation the request:
php artisan make:request CreateUserRequest
2. Custom the validation rules:
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class CreateUserRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* #return bool
*/
public function authorize()
{
// you specify here a previous condition before access to the method
// can be Auth::check() for example
return true;
}
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
return [
// put here your validation rules like:
'first_name' => 'required|string|max:100',
];
}
3. Modify the method in your controller:
public function store(CreateUserRequest $request)
{
// getting all the attributes
$data = $request->only('first_name', 'last_name', 'other_attribute..');
// creating the object
$user = new User;
// adding data
$user->fill($data);
// saving in database
$user->save();
return response()->json([
"message" => "The user has been created.",
"data" => $user,
], 201);
}
* Notice that the $request used as an argument is of type CreateUserRequest, so this indicates to Laravel wath rules to apply.
We have also only pull the data that we want to store (check the $request->only part), that seemed to be the root of your problem.

yii2 user-defined validation of mobile number

i am new to Yii2. I want to validate mobile number by custom validation function. How can i validate mobile no in Yii2 and how can i use user-defined rule to yii2 and How can we add error message to any attribute in yii2 after form post? Thanks in advance
you need to edit your model. Lets say you have the following model:
class User extends ActiveRecord implements IdentityInterface
{
...
/**
* #inheritdoc
*/
public function rules()
{
return [
[['email', 'password', 'id'], 'required'],
[['email', 'username'], 'unique'],
['mobile', 'customValidation'] //<----this will be your custom validation
}
public function customValidation(){
//perform your validation here
if(/*has error*/){
$this->addError("mobile","Your mobile number is not valid.");
}
}
}
the addError method's first parameter is the atribute you want to add the error to and the second parameter is the message you want to show.
Hope this helps ;)
Maybe this could help anyone.
Use pattern match in Yii2 and validate your input field.
It's going to check and return alert message if number has less/more than 10 digits.
['mobile', 'match', 'pattern'=>"/^[0-9]{3}[0-9]{3}[0-9]{2}[0-9]{2}$/",'message'=> 'Not Correct Format - mobile number should have 10 digits.'],

How to ignore uniqueness for multiple fields

I have two models: Cities and Schools. As you already understand Cities can have many schools and taking this into account I have defined my model as follows:
class School extends Model
{
public $fillable = ['city_id' ,'name'];
public function city()
{
return $this->belongsTo('App\City','city_id','id');
}
}
class City extends Model
{
public $fillable = ['name'];
Public function schools()
{
return $this->hasMany('App\School', 'id','city_id');
}
}
But I have faced a pproblem when trying to validate update of a school model. I have to validate whether name of the school is unique for selected city or not. I have defined the rule like this:
$rules = array(
'name' => ['required', Rule::unique('schools')->ignore($id)],
);
$validator=Validator::make(Input::all(),$rules);
But it is not allowing to save a school with existing name in other city than selected. How should I change the rule to ensure that school names can be same if the city is different.
Thank you.
Custom rule
The best solution would be to create a custom rule for this, that accepts the field with the corresponding city name/id as a parameter.
Something like
//Calling the custom rule like this
['name' => 'required|validateSchool:yourFieldNameOfCityHere'];
Declaring the custom validation function in your service provider like this
Validator::extend('validateSchool', function ($attribute, $value, $parameters, $validator) {
$cityName = ($validator->data, $parameters[0]);
//Now check if the $value is already set for the specific city by using normal database queries and comparison
return count(City::whereName($cityName)->schools()->whereName($value)->get()) == 0
});
What does it
The custom validation rule receives the data of the field you give with the function (in the code above it's yourFieldNameOfCityHere), so it knows which city the user chose. With this information, you now can check if there is already a school with the name for the entered city.
At the DB level, it sounds like what you want is a compound uniqueness constraint across name and city_id. Eloquent seems to support passing an array of column names in model definitions. It seems like this requires custom validation, though. See Laravel 4: making a combination of values/columns unique and the custom validator at https://github.com/felixkiss/uniquewith-validator

Validating Collections in Zend Framework2

people..
My problem is:
I have a form, with a Collection, so, I setted a CollectionInputFilter to this Collection..
If i send two block of fields (collections) to validate, and one field of one of this block is validated, the same field in the another one block is automatically validated too, even if is wrong or not filled..
I don't know what to do.. I tried a lot of tips.. but, none worked..
Someone can help me? Or faced the same problem?
Here my code:
class ClienteEnderecoFilter extends CollectionInputFilter
{
public function __construct()
{
$this->add(array(
'name' => 'fieldOne',
'required' => true,
));
}
}
If i send two fieldOne and one is filled, the another one is validated too!
I think you need to set the input filter for each collection item on to the CollectionInputFilter instead of extending it. Like this:
use Zend\InputFilter\InputFilter;
class ClienteEnderecoFilter extends InputFilter
{
public function __construct()
{
$this->add(array(
'name' => 'fieldOne',
'required' => true,
));
}
}
$collectionInputFilter = new CollectionInputFilter();
$collectionInputFilter->setInputFilter(new ClienteEnderecoFilter());

Categories