$this->add() adds the element to the form, thats why it works when you move it above. I can't test your exact scenario at the moment because I'm at work, but I can show you how I realised custom validator for Google Recaptcha. You should be able to use it for your situtation:
My recaptcha field:
$recaptcha = new \Helpers\Recaptcha($name);
$recaptcha->addValidator(new \Helpers\RecaptchaValidator([
'message' => $this->translations->public->forms->recaptchaError
]));
My validator class:
class RecaptchaValidator extends Validator implements ValidatorInterface
{
public function validate(\Phalcon\Validation $validation, $attribute)
{
$value = $validation->getValue('g-recaptcha-response');
$ip = $validation->request->getClientAddress();
if (!$this->verify($value, $ip)) {
$validation->appendMessage(new Message($this->getOption('message'), $attribute, 'Recaptcha'));
return false;
}
return true;
}
/**
* Verify recaptcha response
*
* @param string $value
* @param string $ip
* @return bool
*/
protected function verify($value, $ip)
{
$config = loadConfig();
$params = [
'secret' => $config->sensitive->recaptcha->privateKey,
'response' => $value,
'remoteip' => $ip
];
$response = json_decode(file_get_contents('https://www.google.com/recaptcha/api/siteverify?' . http_build_query($params)));
return (bool)$response->success;
}
}
As you can see I'm not passing values to the validator, but getting the input values inside the Custom validator class.
In the valdiate() method above you can see how I'm accessing the input value, there you can get Username and Password values and check if login is correct.