Symfony2 UniqueEntity Validation and custom message - validation

I have a problem with the custom message in the validator.
I use embedded forms and when I save data to DB some embedded form has a value already exists in DB. When constraint prevents save I get the error 'Sprzęt o takim identyfikatorze już istnieje', but I don't know which.
It's possible display in message bad value?
I read the documentation and I found about {{ limit }} for min, max but I can find nothing about UniqueEntity.
AppBundle\Entity\Hardware:
constraints:
- Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity:
fields: [sn]
message: 'Sprzęt o takim identyfikatorze już istnieje.'
groups: [inventory]

Related

D365 - UCI - A validation error occurred. The value 895390001 of 'MULTISELECT' on record of type ENTITY' is outside the valid range. Accepted Values:

I am trying to use the Multiselect option set and want to build it dynamically, the addOption() is populating the multiselect field correctly, but on save of record it is prompting the validation error.
On change of contact lookup, I am populating the abc_multiselect field. It is populating fine dynamically then user selects the required options from multiselect field, but on save of record (Ribbon Save button not custom save event of form) the CRM is not accepting the values.
MSCRM Version
Server version: 9.2.22081.00182
Client version: 1.4.4647-2208.1
function polulate(executionContext){
var formContext = executionContext.getFormContext();
var multiselect = formContext.getControl("abc_multiselect");
var high = {value : 895390001, text : "High"};
multiselect.addOption(high);
}
The error is;
On Popup
One or more of the option values for this picklist are not in the range of allowed values.
Details
Exception Message: A validation error occurred. The value 895390001 of 'abc_multiselect' on record of type 'abc_ENTITY' is outside the valid range. Accepted Values:
ErrorCode: -2147204326
HexErrorCode: 0x8004431a
ErrorDetails:
ApiExceptionSourceKey: Plugin/Microsoft.Crm.ObjectModel.TargetAttributeValidationPlugin
ApiStepKey: fc743e7d-fbea-4695-bdb9-7d78334c8474
ApiDepthKey: 1
ApiActivityIdKey: 3907c6d7-ef4a-437e-946f-55e0f956fc3e
ApiPluginSolutionNameKey: System
ApiStepSolutionNameKey: System
ApiExceptionCategory: ClientError
ApiExceptionMessageName: PicklistValueOutOfRange
ApiExceptionHttpStatusCode: 400
HelpLink: http://go.microsoft.com/fwlink/?LinkID=398563&error=Microsoft.Crm.CrmException%3a8004431a&client=platform
TraceText:
[Microsoft.Crm.ObjectModel: Microsoft.Crm.ObjectModel.TargetAttributeValidationPlugin]
[fc743e7d-fbea-4695-bdb9-7d78334c8474: TargetAttributeValidationPlugin]
Activity Id: 28d5f67f-bf24-4eca-9124-cf95cf06dc30
I also tried to make all option set values hard coded (Added during the multiselect field creation), it worked smoothly. No issue ! But on dynamically population; on save, the CRM is not accepting the values.
I have tried this , this, this and this but all in vain.
Any one can guide, what is missing?
Update 1
function polulate(executionContext){
var formContext = executionContext.getFormContext();
var multiselect = formContext.getControl("abc_multiselect");
multiselect.clearOptions();
var high = {value : 895390001, text : "High"};
multiselect.addOption(high);
}
I also checked by changing the value from 895390001 to 895390000 and even to 100 and 101 but still same issue.
https://stackoverflow.com/a/48011975/5436880
This should solve your issue? most probably option set does not have 895390001 or it is already selected. you could also try to clear all option sets and then add
clear options
For using addOption those options need to be there in metadata first. You cannot add an option that is not present in metadata. Example can be Suppose you have Option A, 1 and 3 in Metadata. now you want to add another option 4 using Javascript "addOption", it is not possible.
In your case, get a maximum possible set or options in the optionset now onload of form or Onchange of field "removeOption " the options that are not required.

Formik Yup Validation of array of strings not working

I am using formik validations with Yup. I have created a customize react select component to select multiple options. When the user selects an option, its id will push to an array. This is a required field. So I have used this code to validate it, but the error message will not appear.
interest: Yup.array().of(Yup.string().required("This field is required"))
Then I tried this one. Then the error message will appear but when I select the options, the error message will not disappear.
interest: Yup.array().min(1, "at least 1").required("This field is required")
This is initial values:
const formik = useFormik({
initialValues: {
interest:[]
}
})
Also, I need to set the maximum value is 10.
Formik will add the error to the errors object that you can get from the Formikbag. If the error is being added to the list then you can choose to show an error message by displaying it in your component. To my knowledge it won't display the error automatically unless you use the formik ErrorMessage component.
Example: https://formik.org/docs/api/errormessage

Use Validation in FormType or in Entity / Yaml

Which Differents are when use Validation Entity or in Yaml or in FormType?
form Type
....
->add('email', 'text', array (
'constraints' => array (
new Email(array('message' => 'error Email'))
)
))
....
YAML
properties:
email:
- Email:
message: error Email.
Entity
{
/**
* #Assert\Email(
* message = "error Email",
* )
*/
protected $email;
}
All These methods are the same ?
They are not the same! You mixed up entity validation and form validation:
Entity validation belong to entities. This means that it isn't matter whether the new data come from a form or ajax query or you just set some constant data. Validation is triggered by calling a validation on the entity. Note: entity validation runs on form validation too.
Form validation belong to forms. This means that you can validate form values with them (on calling $form->isValid()). But this can result invalid entities because nothing guarantees that your entities will be consistent (just the forms).
For this reason Symfony recommends using entity validation instead of form validators.
Apart from that, there is no difference among annotation, yml, xml or php format. Only the precedences.
I think they would apply the same validation constraints.
I tend to keep all constraints in validation.yml because in my point of view is the most clean way to do it. Also more compatible with Translations.
But all depends on the context and the project you are working on.
UPDATE: After reading Riska's entry I agree with him. The result at the end is the same, but he has the right point there.
Is there a way to use the same validation.yml so the constraints applied to entites are applied to the formtype as well
for instance, if title field in entity is 50charsm ax length, title field in formttype as well.
so we can avoid specifying max length in the add-method of the formtype.
In summary
how to use entity validation constraint in formtype so same constraitn ( required max length ) etc are auto applied ?

UniqueEntity on multiple fields doesn't show an error message

I've added the following constraint to my entity:
* #ORM\Table(name="link", uniqueConstraints={#ORM\UniqueConstraint(name="unique_link_idx", columns={"first_form_id", "first_question_id","last_form_id","last_question_id"})})
* #UniqueEntity(fields={"firstForm", "firstQuestion","lastForm","lastQuestion"}, message="Cette liaison existe déjà !")
* #ORM\Entity(repositoryClass="Ineat\LinkQuestionBundle\Entity\LinkRepository")
The UniqueEntity constraint works well because before adding it, when trying to insert the exact same entity to the DB I had a DBALException abount integrity constraint.
Since then I havn't this exception anymore, the form isn't validating but {{ form_errors(form) }} doesn't print any message.
After having checked in the controller $form->getErrors() returns an empty array while $form->getErrorsAsString() contains the UniqueENtity constraint.
How can I have my UniqueEntity's constraint error message showing
As the UniqueEntity validation seems to fail in one of your child-forms ...
(as the error message is only present in getErrorsAsString and not in getErrors)
... in order to have the child-form errors available in your parent-form use error-bubbling:
$formBuilder->add('child-form','child-form-type', array(
'error_bubbling' => true,
)
)
... or inside your child form:
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'error_bubbling' => true,
));
}
Sometimes the issue occurs because the entity isn't binding the error message to the right field. Using the validation.yml file gives you more control over how and where the error message should be treated.
# src/Ineat/LinkQuestionBundle/Resources/config/validation.yml
Ineat\LinkQuestionBundle\Entity\LinkRepository:
constraints:
- Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity:
fields: [firstForm, firstQuestion, lastForm, lastQuestion]
errorPath: lastQuestion
message: 'This port is already in use on that host.'
More information here : Symfony - UniqueEntity
Also putting text strings into "translation" files is good practice (even if you only use/have one language). You won't have bits of text lying around in your views / entities / forms / controllers ... They will all be in you translation folder, in one location. Duplicate strings can also be changed all at once if necessary. It would look like this :
# src/Ineat/LinkQuestionBundle/Resources/config/validation.yml
Ineat\LinkQuestionBundle\Entity\LinkRepository:
constraints:
- Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity:
fields: [firstForm, firstQuestion, lastForm, lastQuestion]
errorPath: lastQuestion
message: 'linkquestion.form.errors.unique'
# src/Ineat/LinkQuestionBundle/Resources/translations/validators.fr.yml
linkquestion:
form:
errors:
unique: "This port is already in use on that host."
# Or which ever structure you choose.
Then just tell your application that it will always be in French.

Propel ORM Version 1.6.4 -understanding validators

(reworded the question hours later to be more descriptive)
I need a little advice on understanding Propel setters/validators in a standalone (non-framework) development.
The documentation on validation states:
Validators help you to validate an input before persisting it to the database.
... and in validator messages we can provided coherent advice on where users can correct entries that don't pass Propel validation.
The sample usage of a validator reads:
$user = new User();
$user->setUsername("foo"); // only 3 in length, which is too short...
if ($objUser->validate()) {
...
The problem I have found with this is 'what if you cannot setXXX() in order to validate it?'
I have a column type DATE and I invite a visitor to enter a date in a web form. They mistype the date and submit 03/18/20q2
I would hope that one of my custom validators would be able to report a validator message and return the form once more to the user to be amended, however this occurs first:
Fatal error: Uncaught exception 'PropelException' with message 'Error parsing date/time value: '03/18/20q2' [wrapped: DateTime::__construct() [<a href='datetime.--construct'>datetime.--construct</a>]: Failed to parse time string (03/18/aaa) at position 5 (/):
In my tests I couldn't get any simple or CustomValidator to fire once I'd written (for example):
$event= new Event();
$event->setDateStart($form_value_for_date); // where values is "03/18/20q2"
I understand why this is so - it would not make sense to be able to create and try to manipulate a new object if you cannot rely on its fields, even before you save it.
The dilemma this gives me is:
If a fatal error can result from invalid entry preventing Propel validation from handling it for me (and therefore the user) and sending back a useful message, should I bother with Propel validation as well as my own security/courtesy validation ?
I cannot find any mention in the docs of what happens if you give Propel - for whatever reason - a value it doesn't anticipate for the field, or how to handle it.
I do hope this makes sense and that someone can point me at a method that will mean I only need to validate input in one place.
I've hacked together a rough ready solution that will allow me to:
Pre-validate a field against a CustomValidator without setting it in the new object
Retrieve the validator's message for return to the user
I take the form input, sanitise it of course, and then create an object:
$event = new Event();
With my user form in mind, I then pre-check the field I know will fatally fall over if the content's bad, and only set the field in my new object if it would validate:
if ($check = $event->flightCheckFail('StartingDate','DateValidator',$sanitisedFormVal))
echo $check;
else
$event->setStartingDate($sanitisedFormVal);
Method flightCheckFail() will return false if the data from the form would validate against the field, it returns the validator's error message if it would fail.
The method's added to my Event class as follows. Its arguments are the field name, the class of the CustomValidator (which simply runs an strtotime check), and the sanitised form value:
public function flightCheckFail($name,$validatorClass,$value) {
$colname = $this->getPeer()->getTableMap()->getColumnByPhpName($name)->getName();
$validators = $this->getPeer()->getTableMap()->getColumn($colname)->getValidators();
foreach($validators as $validatorMap)
if ($validatorMap->getClass() == $validatorClass) {
$validator = BasePeer::getValidator($validatorMap->getClass());
if ( $validator->isValid($validatorMap, $value) === false)
$failureMessage = $validatorMap->getMessage();
} // if $validatorMap->getClass() == $validatorClass
if($failureMessage)
return $failureMessage;
else
return false;
}
I should be able to use this to work around handling dates in forms, but I'll need to check what other types in Propel might require this sort of handling.
I can stop the form handling wherever this reports a validator error message and send it back. When the user enters valid data, Propel (and normal Propel Validation) gets to continue as normal.
If anyone can improve on this I'd love to see your results.
You could also use a MatchValidator, with a date RegExp, no need for extra functions

Resources