Abhoryo / APYJsFormValidationBundle

This bundle performs validations of a form in javascript. (i18n compatible and several javascript frameworks supported)
92 stars 23 forks source link

Fix issue #8 Symfony 2.1 compability issue #9

Closed recipe closed 11 years ago

recipe commented 11 years ago

For Symfony 2.0 support I expect you'll create tag in your bundle. Also you have to create composer.json file and publish bundle in packagist.org.

Abhoryo commented 11 years ago

There are only these changes ?

I'll do that next week. Thank you.

recipe commented 11 years ago

Yes. BETA3 release had more changes even than BETA4. They did rollback of several interfaces, praise to God. :)

recipe commented 11 years ago

How to use validation based on getter method.

    // My\UserBundle\Entity\Type\UserType
    // ...
    /**
     * (non-PHPdoc)
     * @see Symfony\Component\Form.AbstractType::setDefaultOptions()
     */
    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $ret = array(
            'data_class' => 'My\UserBundle\Entity\User',
            // Read more http://symfony.com/blog/form-goodness-in-symfony-2-1
            'error_mapping' => array(
                'isPasswordLegal' => 'password',
                'isPasswordStrict' => 'password',
            ),
        );
    // My\UserBundle\Entity\User
    // ...
    /**
     * @Assert\True(message = "user.assertion.password.cannot.mach.username")
     */
    public function isPasswordLegal ()
    {
        return ((empty($this->password) || empty($this->username)) || ($this->username != $this->password)) ? true : false;
    }

    /**
     * @Assert\True(message = "user.assertion.password.strict.rules")
     */
    public function isPasswordStrict ()
    {
        return preg_match("/[0-9]/", $this->password) &&
               preg_match("/[^0-9]/", $this->password) &&
               preg_match("/[^\w]|_/", $this->password) ? true : false;
    }

Then we should create javascript handlers for an each getter method. We may ignore this step if we do not want client side verification.

//app/Resources/APYJsFormValidationBundle/views/Getters/User.isPasswordLegal.js.twig
function {{ name|raw }} () {
    var field_password = $("#{{ form.password.first.vars.id|e('js') }}");
    var field_username = $("#{{ form.username.vars.id|e('js') }}");
    var password_val = field_password.val(), username_val = field_username.val();

    return (password_val == '' || username_val == '' || username_val != password_val) ? true : false;
};
//app/Resources/APYJsFormValidationBundle/views/Getters/User.isPasswordStrict.js.twig
// or you can place it within your bundle where entity is
// MyUserBundle:Getters:User.isPasswordStrict.js.twig

function {{ name|raw }} () {
    var errorMessage, level = 0;
    var field_password = $("#{{ form.password.first.vars.id|e('js') }}");
    var value = field_password.val();

    if (value.match(/[0-9]/)) level++;
    if (value.match(/[^0-9]/)) level++;
    if (value.match(/[^\w]|_/)) level++;

    return level == 3;
};

What for UniqueEntity, we should implement universal controller with special route (_format = json) which will use entity manager to check uniqueness.

Abhoryo commented 11 years ago

This is a lots of code you have here. Thanks, I'll take a look.

We can use this universal route for file check too.

Abhoryo commented 11 years ago

Getter constraints are the same as other constraints ? Can't we merge the loops ?

recipe commented 11 years ago

1) Getters determines the way how we retrieve the value and then this value is applied to constraints. Constraints are the same. 2) Getter may have no relation with certain form field. (line 133) Assertion in this case will display at the top of the form.

If we decide to merge loops it will dramatically change implementation of the FieldsConstraints interface and twig template.

Abhoryo commented 11 years ago

Ok, I understand. What is the best, separated loops ?

Can you add some documentation about validations based on getter method before I'll merge it?

recipe commented 11 years ago

I think it no sence to merge loops in this case. I can add/update documentation. Provide me with proposals what file i should amend and what add. Also i going to carry UniqueEntity through. Or you have your own considerations and plans on this matter?

Abhoryo commented 11 years ago

Ok for the loops.

You can add doc in this file: overriding_the_bundle.md but I think that create a new file to explain how to define personnal constraints is a better idea. (add_your_constraints.md)

For the UniqueEntity constraint (UniqueEntityValidator.js.twig), it's good for me but I don't understand why you use a cache.

recipe commented 11 years ago

I'm using cache in order not to produce extra requests to the server (requests are asynchronous) and provide correct UI behaviour. For exmample, onblur event in the first turn returns true, but it will send ajax request, which in the few seconds returns true or false. If false it marks field as invalid. Returned value will be stored in the cache in order to either onsubmit event or onblur event does not initiate request to the server again and return cached response immediately.

I'll do documentation. I'm working on controller for uniqueEntity.

Abhoryo commented 11 years ago

Yeah, you're right, we can add a delay too before send the good request if the user don't have finish typing.

recipe commented 11 years ago

We need not in delay there, because we don't bind onkeyup events. Only onblur and onsubmit.

Abhoryo commented 11 years ago

Oh sorry I hadn't seen your last commit.

Abhoryo commented 11 years ago

Why can't we use the find method of a repository directly ? It can use an array of criterias too.

recipe commented 11 years ago

my pros and cons.

  1. Entity may not have appropriated repository. User may ignore to use it.
  2. Repository class may not have conventional name and location.
  3. How with find method to do queries such as WHERE u.email = ? AND NOT (u.pk1 = ? AND u.pk2= ?)