0

I've some areas in my form something like:

<ul>
<li>
<input type="checkbox" name="post_categories[]" value="16">English First Main Category<br>
<ul>
<li><input type="checkbox" name="post_categories[]" value="17">English First Subcategory<br></li>
</ul>
</li>
</ul>

When I try to validate them as required fields or something else, Laravel did not validate rules. My rules something like below (In /application/models/posts.php):

public static $rules = array(

    'post_title' => 'required',
    'post_body' => 'required',
    'content_language'=>'required|alpha',
    'post_categories'=>'array_numeric',
    'post_sequence_number'=>'numeric'

    );


public static function validate($data){ 

    return Validator::make($data, static::$rules);

}

In /application/library/validate.php I've a function that validates the array is numeric or not:

Class Validator extends Laravel\Validator {

        public function validate_array_numeric($attribute, $value, $parameters){
            $numeric_values = array_filter($value, create_function('$item', 'return (is_numeric($item));'));
            return count($numeric_values) == count($value);
        }

    }

Rules works perfectly, except post_categories[]. I get the error:

Method [array_numeric] does not exist.

Cheers.

dr.linux
  • 752
  • 5
  • 15
  • 37

3 Answers3

5

I had to solve the same problem. Here's what I did:

I created a custom class that extends the default Laravel\Validator class. I wanted to be able to tell the validator when I'm dealing with multiple values (like in your case). In my implementation this could be done by appending '_array' to every validation rule for a certain field name. What my class does is to check if the rule name has this suffix and if it does the value parameter (which is an array in this case) is broken down to its contained items and passed to the default validation functions in Laravel.

<?php

class Validator extends Laravel\Validator {

  public function __call($method, $parameters)
  {
      if (substr($method, -6) === '_array')
      {
          $method = substr($method, 0, -6);
          $values = $parameters[1];
          $success = true;
          foreach ($values as $value) {
              $parameters[1] = $value;
              $success &= call_user_func_array(array($this, $method), $parameters);
          }
          return $success;
      }
      else 
      {
          return parent::__call($method, $parameters);
      }
  }

  protected function getMessage($attribute, $rule)
  {
      if (substr($rule, -6) === '_array')
      {
          $rule = substr($rule, 0, -6);
      }

      return parent::getMessage($attribute, $rule);
  }
}

As stated in the posts above you will have to make the following change so that your custom Validator class can be found by the Autoloader:

Then you need to remove the following line from application/config/application.php file:

'Validator' => 'Laravel\Validator'

When this is done you'll be able to use all of Laravel's validation rules with the '_array' suffix. Here's an example:

public static $rules = array(
  'post_categories'=>'required_array|alpha_array'
);
planewalker
  • 298
  • 2
  • 12
  • 1
    I checked the code and I think it should be getMessage($attribute, $rule) – llt Aug 30 '13 at 12:24
  • @planewalker I've started a question [here](http://stackoverflow.com/questions/18894362/laravel-4-form-validation-extending-the-call-method) basing your answer. I'd appreciate if you could check when you're available. – Arda Sep 19 '13 at 12:17
3

I don't know if this issue has been solved in Laravel 4. Maybe you can try it. But what I'm doing right now is extending the validation class.

You can create a new library that extends the validation class. To validate if all the items in the array has numeric values. This is in application/libraries:

class Validator extends Laravel\Validator {

    public function validate_arraynumeric($attribute, $value, $parameters){
        $numeric_values = array_filter($value, create_function('$item', 'return (is_numeric($item));'));
        return count($numeric_values) == count($value);
    }

}

To change the default error message when the validation fails. Go to application/language/en/validation.php. Just use the name of the function as the key for the new array item:

"arraynumeric"   => "The :attribute contains non-numeric values",

update

Then you need to remove the following line from application/config/application.php file:

'Validator' => 'Laravel\\Validator'

To use the new validation:

public static $rules = array(
'post_categories'=>'array_numeric'
);

Now for the required checkbox. I assume you're just requiring one checkbox to be checked. You can just check in the function for the new validation the count of the checked checkboxes if it is at least 1.

Wern Ancheta
  • 22,397
  • 38
  • 100
  • 139
  • can you post your code? maybe update your original question so that I could see. As you might have noticed already there's a bit of a typo. Instead of calling `arraynumeric` I called `array_numeric` – Wern Ancheta Dec 21 '12 at 22:49
  • I have updated my answer. Though I know you have already figured it out. – Wern Ancheta Jan 03 '13 at 15:17
0

You're doing something strange here.

Using post_categories[] as form names generates an array. This means you cannot validate it with 'post_categories[]'=>'required|numeric'. Instead you have to loop through the array and validate each field on it's own.

aebersold
  • 11,286
  • 2
  • 20
  • 29