I'm separating chunks of my validation code from my model's validation() method into reusable \Phalcon\Validation components. A realistic scenario for why i'm doing this is I have a set of Validators for validating an account email (using StringLength and Email validators). I need to reuse this "account email validator" that's consisted of many validators to validate an email passed in to a login action method.
I ran into a problem where appending messages to my model via the mode's appendMessage() method does not cause the model validation to fail. So it appears Phalcon doesn't look at the length of the validation messages in a model before determining if validation failed?
So my question is: How can I manually trigger a model's validation to fail in the mode's validation() method after I manually append new validation messages?
Here's my custom email validator:
/**
* Validates an email that is associated to a Player model.
*
* @package App\Validators\Players
*/
class PlayerEmailValidator extends Validation
{
public function initialize()
{
$this->add('Email', new Email([
'message' => 'Please enter a valid email.'
]));
$this->add('Email', new StringLength([
'message' => 'We only accept emails up to 255 characters long.',
'max' => 255,
'min' => 300 // this is only for testing! I'm intentionally setting this to 300 so I don't have to put in a 300 char email to fail this validation
]));
}
}
Here's my AbstractModel class (all models inherit from this):
abstract class AbstractModel extends Model
{
/**
* Appends a list of messages in a \Phalcon\Validation\Message\Group object to the models validation messages.
*
* @param Group $messages
* @return AbstractModel
*/
protected function appendValidationMessages(Group $messages)
{
foreach($messages as $message)
{
$this->appendMessage(new Message(
$message->getMessage(),
$message->getField(),
$message->getType()
));
}
return $this;
}
}
Here's my AbstractPlayers class (abstract model class generated by Phalcon):
abstract class AbstractPlayers extends AbstractModel
{
/**
*
* @var string
* @Column(type="string", length=255, nullable=false)
*/
protected $Email;
}
Here's my Players model:
class Players extends AbstractPlayers
{
public function validation()
{
$validation = new Validation();
// $validation->add('Email', new Email([
// 'message' => 'Please enter a valid email.'
// ]));
//
// $validation->add('Email', new StringLength([
// 'message' => 'We only accept emails up to 255 characters long.',
// 'max' => 255,
// 'min' => 6
// ]));
$emailValidator = new PlayerEmailValidator();
$this->appendValidationMessages($emailValidator->validate($this));
var_dump($this->validate($validation), $this->getMessages());
return $this->validate($validation);
}
}
Here's the result of var_dump($this->validate($validation), $this->getMessages())
in my Players model.
bool(true)
array(1) {
[0]=>
object(Phalcon\Mvc\Model\Message)#94 (5) {
["_type":protected]=>
string(8) "TooShort"
["_message":protected]=>
string(48) "Field Email must be at least 300 characters long"
["_field":protected]=>
string(5) "Email"
["_model":protected]=>
NULL
["_code":protected]=>
int(0)
}
}