Laravel 4.2 自定义验证器以组合 required_if 或 required_without

Laravel 4.2 custom validator to combine required_if OR required_without

让我描述一下我的情况。这是一个类似于我的表格:

<select name="colors">
  <option value="1">Dark red</option>
  <option value="2">Light red</option>
  <option value="3">Dark green</option>
  <option value="4">Light green</option>
</select>
<input type="text" name="textbox-field">
<input type="checkbox" name="checkbox-field" value="1">

我想根据在 colors 上选择的值来验证 textbox-fieldcheckbox-field。问题是 textbox-fieldcheckbox-field 是互斥的,这意味着当指定的 colors 值已经被选择时,只需要填充其中一个。

如果我有一个字段,我可以像这样使用内置的 required_if 规则:

'textbox-field' => "string|required_if:colors,3,4"

但是,我想实现的是这样的想法,但在最后两个规则之间使用 OR 运算符:

'textbox-field'  => "string|required_if:colors,3,4|required_without:checkbox-field"
'checkbox-field' => "numeric|required_if:colors,3,4|required_without:textbox-field"

是否可以创建自定义验证规则,使用 OR 逻辑运算符组合 required_if 和 required_without?

我通过实施以下自定义验证器解决了这个问题:

/**
 * Class CustomValidator
 * Extends the Illuminate\Validation\Validator class instead of using Validator::extend,
 * it requires access to protected properties of the Validator parent class
 *
 * Note: This needs to be registered in app/start/global.php
 */
class CustomValidator extends Illuminate\Validation\Validator
{

/**
 * The validation rules that imply the field is required.
 *
 * @var array
 */
protected $implicitRules = array(
    'Required',
    'RequiredWith',
    'RequiredWithAll',
    'RequiredWithout',
    'RequiredWithoutAll',
    'RequiredIf',
    'Accepted',
    'RequiredIfValueSelectedOrWithoutField'
);
/**
 * Validate mutually exclusive fields when specific options have been selected in select input
 * This uses the built-in rules and apply them using the OR logical operator
 *
 * @param $attribute
 * @param $value
 * @param $parameters
 *
 * @return bool
 */
public function validateRequiredIfValueSelectedOrWithoutField($attribute, $value, $parameters) {

    // use the required_if bult-in rule to check if the required options are selected in select input
    $valueSelectedParams = array_merge(['my_select_input'],Model::getArrayWithTheSpecifiedOptions());
    $isValidForSelect = $this->validateRequiredIf($attribute, $value, $valueSelectedParams);

    // use the required_without to check if the mutually exclusive field in parameters[0] has a value
    $isValidForMutualExclusiveField = $this->validateRequiredWithout($attribute, $value, [$parameters[0]]);

    // returns the result by applying OR between the required_if and the required_without rules
    return ($isValidForSelect || $isValidForMutualExclusiveField);
}

/**
 * Replace the :other placeholder with the select input localized literal to display correctly in error messages
 *
 * @param $message
 *
 * @return mixed
 */
protected function replaceDangerousEkaOrField($message)
{
    return str_replace(':other', Lang::get('model.my_select_input'), $message);
}

我把它放在 app/helpers/CustomValidator.php 中并在我的 app/start/global.php 末尾注册:

/*
|--------------------------------------------------------------------------
| Register Custom Validator extending Illuminate\Validation\Validator
|--------------------------------------------------------------------------
*/

Validator::resolver(function($translator, $data, $rules, $messages)
{
    return new CustomValidator($translator, $data, $rules, $messages);
});

还需要 运行 composer dump-autoload 将新的 class 添加到 classloader。

我希望这对以后处于类似位置的任何人有所帮助。干杯!