FormControls should reference their containing Form

Bug #3568 reported by wouter bolsterlee
2
Affects Status Importance Assigned to Milestone
Anewt
Fix Released
Medium
wouter bolsterlee

Bug Description

FormControl instances should hold a reference to their Container. This come in handy especially when controls have to query the form or to even change it (needed for file uploads + form encoding).

At a slightly related note: maybe validators should also be able to reference their associated control, but this breaks the "use validators without a form" use case.

Revision history for this message
Berend (mpe) (mpe) wrote :

First point looks sound.

Second point: what usercases would be supported? As said, it only limits portability of the validator.

Revision history for this message
wouter bolsterlee (wbolster) wrote :

I heard your complains about the simplicity of the error messages: it's currently only possible to tell the user "this control is incorrect", whereas it would be nice if we could differentiate on what validator failed for what reason.

Two options come to mind here:

1) Add (translatable) error strings to validators, which the validators then sets on the associated form control. This would need a reference in the validator to a control, or the control code that calls the validator should get('last_error') or something like that on the failed validator and set that as its own error string.

2) Provide an extra string parameter to the add_validator() method on form controls, which would be used as the error string if that particular validator fails to pass. This possible solution wouldn't need a reference to the form at all, but limits the number of possible error strings to one per validator, whereas the option (1) would allow a validator to return various error messages.

I'm in favor of the second option. The 'single error message per validator' limitation does not pose a real problem I think, because all Validators (and custom ones should too!) are suited for just one simple check (string too long, value too low, invalid email, ...).

Revision history for this message
Berend (mpe) (mpe) wrote :

The second option has my vote too, as a special usecase when an control yields multiple values to check:

FileuploadValidator will be split up in multiple validators since the value of a file input control (found in $_FILES) is an array with multiple values. So each one of these validators accepts an associative array at is_valid() but they will check and report errors for only one array value.

(PHP processes an uploaded file to an array with keys 'size', 'name', 'error', 'tmp_name' and 'type')

Changed in anewt:
assignee: nobody → uws
status: New → Accepted
Revision history for this message
wouter bolsterlee (wbolster) wrote : Proposed patch

This adds a reference $form to all form controls that are added using add_control() method on Form.

Revision history for this message
wouter bolsterlee (wbolster) wrote :

Berend, could you please test this, so that this bug may be closed?

Revision history for this message
Berend (mpe) (mpe) wrote :

This bug will be solved together with 3564 "Form lib should have FileuploadControl".

The reference is all working, but the next problem is how the errormessages are handled. I was in favor of one message per validator, but it's turning out a bit restrictive.

So, slightly extending Wouters' 2nd proposal with some container voodoo:

To set a custom error message:

    $control->add_validator($v_size, 'Too big.');

add_validator will put the string into the validator-container as 'error_msg'. So this will yield the same results:

    $v_size->set('error_msg', 'Too Big.');
    $control->add_validator($v_size);

Now $validator::get_error() returns _getvar('error_msg') if its set, otherwise its falls back on _getvar('error'). _All_ validators must specify this default 'error' and $my_validator->get_error() may only be called if is_valid() returns false.

This makes that with no custom message:

    $control->add_validator($v_size);

the validator will return its default error. This is possibly a specific message set during the is_valid() check or a fixed message set in the constructor.

API breakage
this will deprecate any $control->set('error', 'my msg') usage, controls only known about errors via their validators. In other words, controls without validators can't fail and as such can't have an error. Also all validators must be edited or Validator must get a standard error.

Does this look sane? I know that moving all error msgs to the validator will break some existing code but I think it's the best solution. Patch and new files follow.

Revision history for this message
Berend (mpe) (mpe) wrote : fileupload.patch

Before commit all validators must be rewritten or Validator must get an additional patch.

Revision history for this message
Berend (mpe) (mpe) wrote : anewt/validators/filevalidator.lib.php

New file.
 - FileErrorValidator works but could use some review.
 - FileNameValidator depends on bug 3279

Revision history for this message
Berend (mpe) (mpe) wrote : anwt/validator/imagevalidator.lib.php

New validator, returns valid if file is of mimetype 'image/*'

Revision history for this message
wouter bolsterlee (wbolster) wrote :

Closing, this is fixed.

The patches for the FileUploadControl will be attached to bug #3564.

Changed in anewt:
status: Accepted → Fixed
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.