Phalcon validate field if exist post data - validation

I've notice that phalcon validation model will do validation no matter the field do exist in post.
public function validation()
{
$this->validate(new Uniqueness(
array(
"field" => "email",
"message" => "The email is already registered"
)
));
$this->validate(new Email(
array(
"field" => "companyEmail",
"message" => "Email format error"
)
));
return $this->validationHasFailed() != true;
}
In this case even if the user is saving other data rather than email, the email field still being verified. How to make it validate only if the field exist? ( for some field its really not needed to validate everytime )
maybe something like
if( *syntax* ){
$this->validate(new Email(
array(
"field" => "companyEmail",
"message" => "Email format error"
)
));
}

Use a form class (subclass of Phalcon\Forms\Form), add code to check for the existence of the variable in your beforeValidate function and only add the validator if the variable is set.
function beforeValidation($data, $entity)
{
...
$elements = $this->getElements();
if (isset($data['fieldname'])) {
$elements['fieldname']->addValidator(new Email(
array(
"field" => "companyEmail",
"message" => "Email format error"
)
))
...
}
}

Here my solution:
if( !empty($this-companyEmail) ){
$this->validate(new Email(
array(
"field" => "companyEmail",
"message" => "Email format error"
)
));
}
I'm doing this as I am passing the variable via ajax

This is my implementation for Phalcon 3.4
class SometimesOf extends \Phalcon\Validation\Validator\PresenceOf
{
public function __construct(array $options = null)
{
parent::__construct($options);
$this->setOption('allowEmpty', true);
if(!$this->hasOption('message')){
$this->setOption('message', 'Field :field cannot be empty');
}
}
public function isAllowEmpty(Validation $validator, $field)
{
$keys = array_keys($validator->getData());
return !in_array($field, $keys, true);
}
}
And in the validator use it as a...
$validation->add('foo', new PresenceOf());
$validation->add('bar', new SometimesOf());
$messages = $validation->validate($data);

Related

How to map errors to the field?

Below is my server side validation in lumen :
$rules = array(
'prog_code' => 'required',
'payer_id' => 'required',
);
$validator = \Validator::make($post, $rules);
if (!$validator->fails()) {
try {
// Start Logic Here
} catch (\Exception $e) {
}
} else {
$errors = $validator->errors();
return response()->json($errors->all());
}
and it return error like below :
[
"The prog code field is required.",
"The payer id field is required.",
]
but the problem is how I map the error of which field because I want to show the error below the particular text field.
Can we customize error like below :
[
[prog_code] => "The prog code field is required.",
[payer_id] => "The payer id field is required.",
]
The way I achieve the same response was to do:
if ( $validator->fails() ) {
$errors = [];
foreach ( $validator->errors()->toArray() as $field => $message ) {
$errors[$field] = $message[0];
}
return response()->json($errors);
}
If you dump the $errors variable you have an array of errors like your target:
ViewErrorBag {#406
#bags: array:1 [
"default" => MessageBag {#407
#messages: array:1 [
"pin" => array:1 [
0 => "The Programming Code is required Sir!"
]
]
#format: ":message"
}
]
}
$errors variable is injected by validator when there are errors

How to exclude a perticular field from unique validation in edit mode in cakephp3.0 validation

I want to validate a field called survey_id which is an input from user for uniqueness. It is working properly and giving the correct response when adding the new record, but when I tried to edit this record it is giving an error [unique] => Provided value already exist. So what I want is to exclude the survey_id of the current record from uniqueness check and if user input some other value for survey_id it should check for uniqueness search.
Currently I am using the CakePHP 3.0 validation with on create validation. Here is the validation rule that I am using:
validator
->requirePresence('survey_id', __('msg_required'))
->notEmpty('survey_id', __('msg_required'))
->maxlength('survey_id', 32, __('msg_maxlength'))
->add('survey_id', 'unique', ['rule' => ['validateUnique',['id']], 'provider' => 'table', 'message' => 'Provided value already exist', 'on'=>'create']);
return $validator;
Is there anything wrong with this code?
Thanks in advance.
`
It will work with this validation rule
$validator
->requirePresence('survey_id', __('msg_required'))
->notEmpty('survey_id', __('msg_required'))
->maxlength('survey_id', 32, __('msg_maxlength'))
->alphaNumeric('survey_id', __('msg_surveyid_format'))
->add('survey_id', 'custom', [
'rule' => function ($value, $context) {
if (!empty($context['data']['projectId'])) { $values = array($context['data']['projectId']); } else { $values = array(); }
$data = $this->getSurveyId($value, $values);
return (!empty($data)) ? false : true;
},
'message' => __('msg_surveyid_exsist')]);
return $validator;
}
public function getSurveyId($surveyId = null, $exclude = null) {
$where = array('p.survey_id' => $surveyId);
if (!empty($exclude) && is_array($exclude)) {
$where[] = array('p.id NOT IN' => $exclude);
}
return $this->db->newQuery()
->select('*')
->from(['p' => 'projects'])
->where($where)
->execute()
->fetch('assoc');
}

In CakePHP3 how do I create a custom model rule which validates that a time is after another time in the same table?

Columns (both datatype time):
Start
End
End cannot be before start.
$validator
->requirePresence('end', 'create')
->notEmpty('end')
->add('end', [
'time' => [
'rule' => 'time',
'message' => 'end can only accept times.'
],
'dependency' => [
'rule' => [$this, 'endBeforeStart'],
'message' => 'end can not be before start.'
],
]);
If it is a PUT request which only contains end, the model will need to query the existing record to compare against start. If it is a PUT which contains both then it need to validate against the intended new parameter.
How does cakePHP3 do this?
private function endBeforeStart($fieldValueToBeValidated, $dataRelatedToTheValidationProcess)
{
//What goes here?
}
I can't seem to find any examples of doing this online.
I'm not quite sure and haven't tested it, but maybe this gives you some hints:
$validator
->add('end', [
'endBeforeStart' => [
'rule' => function ($value, $context) {
// If it's a POST (new entry):
if ( $context['newRecord'] == '1' ) {
// Do your comparison here
// Input values are e.g. in $context['data']['starttime']
// If end is before start:
return false;
}
// If it's a PUT (update):
else {
// If starttime is not in $context['data']['starttime']
// check for the old value in $getOldEntry
$getOldEntry = $this->getOldEntry( $context['data']['id'] );
// And do your comparison here...
// If end is before start:
return false;
}
return true;
},
'message' => 'end can not be before start.' ],
])
public function getOldEntry($id = null) {
return $this->get($id);
}
I'm also not sure if the last function has to be private or public...

CakePHP custom Validation rule checks unique field combination only on create

I have a Database with a User model. These Users should be unique by their name and birthday.
So I wrote a custom validation function called checkUnique
public function checkUnique($check){
$condition = array(
"User.name" => $this->data["User"]["name"],
"User.lastname" => $this->data["User"]["lastname"],
"User.birthday" => $this->data["User"]["birthday"]
);
$result = $this->find("count", array("conditions" => $condition));
return ($result == 0);
}
The validation rule in the model:
"name" => array(
"checkUnique" => array(
"rule" => array("checkUnique"),
"message" => "This User already exists.",
"on" => "create"
),
)
I have two problems.
The first: This validation rule also triggers on update action, implemented as
public function edit($id = null) {
if (!$this->User->exists($id)) {
throw new NotFoundException(__('Invalid User'));
}
if ($this->request->is(array('post', 'put'))) {
if ($this->User->save($this->request->data)) {
$this->Session->setFlash(__('Update done.'));
return $this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash(__('The user can't be saved.'));
}
} else {
$options = array('conditions' => array('User.' . $this->User->primaryKey => $id));
$this->request->data = $this->User->find('first', $options);
}
}
But I wrote "on" => "create", so why it triggers also on update?
The second problem:
If the validation rule only triggers on create, how can I manage, to trigger an validation error, if someone change the name, lastname and birthday like an other user in the Database? Then the unique validation rule should be triggered.
Remove the 'on' => 'create'. (You want to validate in both events).
Modify your custom validation rule to this
public function checkUnique() {
$condition = array(
"User.name" => $this->data["User"]["name"],
"User.lastname" => $this->data["User"]["lastname"],
"User.birthday" => $this->data["User"]["birthday"]
);
if (isset($this->data["User"]["id"])) {
$condition["User.id <>"] = $this->data["User"]["id"];
//your query will be against id different than this one when
//updating
}
$result = $this->find("count", array("conditions" => $condition));
return ($result == 0);
}

update all the records in table not a single record

I am new to codeigniter and working on a codeignter project where i have to update the user record. The id and data of user passed to model are correct, but when i update the record, all the users are updated with the new record. My coding is :
public function updateUser(){
$user = $this->session->userdata('logged_in');
$userID = $user['id'];
$data = array(
"first_name" => $this->input->post('reg_first_name'),
"last_name" => $this->input->post('reg_last_name'),
"mobile" => $this->input->post('reg_mobile'),
"country" => $this->input->post('reg_country'),
"state" => $this->input->post('reg_state'),
"city" => $this->input->post('reg_city'),
"paypal_email" => ''
);
$this->db->update('users',$data);
$this->db->where('id',$userID);
if($this->db->affected_rows() > 0){
return true;
}
else {
return false;
}
}
Is there something wrong in my code, Please help.
Try :
public function updateUser(){
$user = $this->session->userdata('logged_in');
$userID = $user['id'];
$data = array(
"first_name" => $this->input->post('reg_first_name'),
"last_name" => $this->input->post('reg_last_name'),
"mobile" => $this->input->post('reg_mobile'),
"country" => $this->input->post('reg_country'),
"state" => $this->input->post('reg_state'),
"city" => $this->input->post('reg_city'),
"paypal_email" => ''
);
$this->db->where('id',$userID); //changes here where clause should be provided before update
$this->db->update('users',$data);
if($this->db->affected_rows() > 0){
return true;
}
else {
return false;
}
}
yours looks fine but the only problem is... you are updating your DB first and adding where to it..which is not how it should be where should be before the update query.
$this->db->where('id',$userID);
$this->db->update('users',$data);

Resources