Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Sign In with Google Sign In with OpenID

unique validation

It seems that the validation "unique" does not discriminate against the record itself.

So if I try to update a record having a field with "unique" validation I have to change the value of this field in order to save the record.


  • I meant unique to ensure something doesn't exist yet, which is more useful for inserts than updates.

  • If you think it might be helpful I could change Validator.php to handle even the updates.

  • Could you put together an example? I'm not completely sure how your change would work.

  • Needing the primary key and wanting to dirty the least possible the Elefant code, I would create a new type (say unique_update)

    This new type would need three parameters and the presence of the primary key in the form (even hidden).


    unique_update = "table.column.pkey"

    It is not nice but it works.

    I would add $values to validate function (line 108)

    public static function validate ($value, $type, $validator = false, $values = false) {

    I would change its call passing $values (line 335)

    if (! isset ($values[$name]) || ! Validator::validate ($values[$name], $type, $validator, $values)) {

    I would add this case (after line 248)

    case 'unique_update':
        list ($table, $column , $pkey) = preg_split ('/[\.:\/]/', $validator);
        $res = DB::shift ('select ' . $column . ' from ' . $table . ' where ' . $column . ' = ? and ' . $pkey . ' != ?', $value, $values[$pkey]);
        if ($res == $value) {
            return false;
        return true;
  • The pieces of code that I reported fulfill what you asked?

  • To give you a temporary solution while I hum and haw over things and generally just get distracted by work :P, here's how you can add custom validation in the form response handler:

    $form = new Form ('post', $this);
    echo $form->handle (function ($form) {
        if (/* custom validator */) {
            $form->failed[] = 'fieldname';
            return false;

    That will trigger the same as any of the server-side validations.

    I've actually been using that on a project to provide additional validations like this:

    $form = new Form ('post', $this);
    echo $form->handle (function ($form) {
        if (/* validation one */) {
            $form->failed[] = 'field-failure1';
            return false;
        if (/* validation two */) {
            $form->failed[] = 'field-failure2';
            return false;
        // etc.

    Then in the template:

        <label>Field</label><br />
        <input type="text" name="field" value="{{field}}" />
        <span class="notice" id="field-failure1-notice">Failure reason one.</span>
        <span class="notice" id="field-failure2-notice">Failure reason two.</span>

    I think a permanent solution to the validation flexibility might be to pass all the data as an additional array to the callback, so custom callback-based validations can be more flexible. What do you think?

  • edited February 2015

    That's more than what I tried to do.

    In addition to not touch the framework, allows me to have different notice for every failed validation. It works perfectly.

    Just great, thanks!

Sign In or Register to comment.