Я работаю с сохранением изменений в объекте — единственная проблема в том, что эта функция проверки пароля ниже является частью UsersTable, и ее нужно вызывать, даже если я не изменяю поле пароля:
->add('password',[
'custom'=>[
'rule'=> function($value, $context){
$pattern = '$\S*(?=\S{8,})(?=\S*[a-z])(?=\S*[A-Z])(?=\S*[\d])(?=\S*[\W])\S*$';
return (bool)preg_match($pattern, $context['providers']['entity']->beforeHash);
},
'message'=>'Your password must have 1 uppercase letter, 1 lowercase letter, 1 number, and 1 special character ie. !@#$%'
],
])
Я попытался добавить к нему оператор — параметр «on», как описано в документации:
'on' => function ($context) {
return empty($context['providers']['password]);
},
Это позволило мне внести изменения, так как проверка выполняется только тогда, когда поле пустое (т. Е. Когда мы впервые создаем пользователя).
К сожалению, это также сломало мои другие функции — изменить и сбросить пароль. В этих случаях в поле устанавливается пароль, поэтому проверка не будет применяться, когда я пытаюсь изменить или сбросить свой пароль.
Поэтому я поговорил с парнями из Github CakePHP3, и они предложили мне проверить грязное поле, чтобы увидеть, пытается ли пароль измениться.
Это отличная идея, но как мне получить доступ к полю? Как только я углублюсь в массив, я не могу идти дальше:
$context['providers']['entity'] // this returns my object, but doesn't go deep enough
$context['providers']['entity']['dirty'] // this doesn't work - returns null, even though there is data inside on the debug
Так как я могу получить доступ к грязному массиву из контекста, в котором я нахожусь? Если я вижу, что поле пароля обновляется, я могу сделать исключение и устранить проблему.
Нашел это! Для дальнейшего использования, вот как вы это делаете:
dirty () проверяет, было ли изменено поле.
->validatePresence('password', 'create')
->add('password',[
'custom'=>[
'rule'=> function($value, $context){
$pattern = '$\S*(?=\S{8,})(?=\S*[a-z])(?=\S*[A-Z])(?=\S*[\d])(?=\S*[\W])\S*$';
return (bool)preg_match($pattern, $context['providers']['entity']->beforeHash);
},
'on' => function ($context) {
return $context['providers']['entity']->dirty('password');
},
'message'=>'Your password must have 1 uppercase letter, 1 lowercase letter, 1 number, and 1 special character ie. !@#$%'
],
])
Других решений пока нет …