Повторное использование пользовательских методов проверки в CakePHP 2.x

Я хочу проверить в нескольких моделях, составляют ли данный IP-адрес и подсеть действительную сеть.

Я написал эту пользовательскую функцию проверки для одной модели:

public function isValidNetwork($check=null){
    if(isset($this->data[$this->name]['ip']) && isset($this->data[$this->name]['subnet'])){
        $iph = new IpHandler();
        return $iph->isNetwork($this->data[$this->name]['ip'],$this->data[$this->name]['subnet']);
    }
    return false;
}

Как лучше всего повторно использовать эту функцию в других моделях? Может быть, переместить функцию на AppModel?

Но есть еще одна проблема, что ключи не всегда одинаковы.

Можно ли перезаписать правило проверки, чтобы передавать только необходимые параметры? Например:

'subnet' => array(
        'rule' => array('isValidNetwork','ip','subnet'),
        'required' => true,
        'message' => 'No valid network given'
    )

public function isValidNetwork($ip, $subnet){...}

person Michael    schedule 14.01.2016    source источник


Ответы (1)


Правильный способ повторного использования вашего метода проверки — реализовать его в AppModel или в пользовательском поведении.

Что касается разрешения вашему пользовательскому методу проверки для проверки разных имен полей, Cookbook предлагает вам использовать extract_values().

Этот пример был взят из документации:

class Post extends AppModel {

    public $validate = array(
        'slug' => array(
            'rule' => 'alphaNumericDashUnderscore',
            'message' => 'Slug can only be letters,' .
                ' numbers, dash and underscore'
        )
    );

    public function alphaNumericDashUnderscore($check) {
        // $data array is passed using the form field name as the key
        // have to extract the value to make the function generic
        $value = array_values($check);
        $value = $value[0];

        return preg_match('|^[0-9a-zA-Z_-]*$|', $value);
    }
}

Но я думаю, вы могли бы также использовать дополнительные аргументы в качестве ключей для извлечения соответствующих данных.

В массиве $validation:

'subnet' => array(
    'rule' => array('isValidNetwork','ip','subnet'),
    'required' => true,
    'message' => 'No valid network given'
)

И в вашем методе:

public function isValidNetwork($check, $ipFieldName, $subnetFieldName){
    if(isset($this->data[$this->name][$ipFieldName]) && isset($this->data[$this->name][$subnetFieldName])){
        $iph = new IpHandler();
        return $iph->isNetwork($this->data[$this->name][$ipFieldName],$this->data[$this->name][$subnetFieldName]);
    }
    return false;
}

ИЗМЕНИТЬ

Если вы хотите использовать один дополнительный параметр, вы можете сделать следующее:

'ip' => array(
    'rule' => array('isValidNetwork','subnet'),
    'required' => true,
    'message' => 'No valid IP/network given'
)

Ваш пользовательский метод проверки будет выглядеть следующим образом:

public function isValidNetwork($check, $subnetFieldName){
    list($ip) = array_values($check);

    if(!empty($ip)) && !empty($this->data[$this->name][$subnetFieldName])){
        $iph = new IpHandler();
        return $iph->isNetwork($ip,$this->data[$this->name][$subnetFieldName]);
    }
    return false;
}

См. Cookboox 2.x: Данные Проверка: добавление собственных методов проверки

person Inigo Flores    schedule 14.01.2016
comment
Я знаю такую ​​возможность. Но тогда у меня есть неиспользуемый параметр в моем методе. Это не чистый код. Но если невозможно обойти параметр $check, я с вами согласен. - person Michael; 15.01.2016
comment
Возможно, вы можете использовать параметр $check для ссылки на одно из полей и указать другое с помощью одного дополнительного параметра. Это свяжет ваш пользовательский валидатор с основным типом поля (например, ip), оставив дополнительный параметр для другого поля (например, subnet). - person Inigo Flores; 15.01.2016
comment
Отредактировал ответ, чтобы включить эту модификацию. - person Inigo Flores; 15.01.2016