I have made a simple MVC framework of my own for my personal website to learn a thing or two about how this whole thing even works. I think I've got the idea, but there's one thing I'm not sure about.
Now I know that a model shouldn't need anything specific - everything has to be generalized so it's accessible from multiple controllers which do something different.
My main issue, though is: How the hell do I tell the model to save something the way I want it to? If it's generalized, it should have no information about any save table, any output message or any saving pattern to begin with.
Then I remembered that there's this new fancy thing in PHP called closures and this might be a good way to use them. I have decided to deal with validation in the model in this fashion:
Controller:
private function sendMail($data)
{
$rebuilt['name'] = array("type" => "string", "value" => $data['name'], "required" => true);
$rebuilt['email'] = array("type" => "email", "value" => $data['email'], "required" => true);
$rebuilt['subject'] = array("type" => "string", "value" => $data['subject'], "required" => false);
$rebuilt['message'] = array("type" => "string", "value" => $data['message'], "required" => true);
$callback = function() use (&$rebuilt) {
$headers = array();
$headers[] = "MIME-Version: 1.0";
$headers[] = "Content-type: text/plain; charset=utf-8";
$headers[] = "From: {$rebuilt['name']['value']} <{$rebuilt['email']['value']}>";
$headers[] = "Subject: {$rebuilt['subject']['value']}";
$headers[] = "X-Mailer: PHP/".phpversion();
mail("some@email", $rebuilt['subject']['value'], $rebuilt['message']['value'], implode("\r\n", $headers));
};
$this->model->validateInput($rebuilt, $callback, 'contact', "SuccessEmailReceived", 'contact');
}
Model validateInput() method:
public function validateInput(&$validation, $function, $failAnchor = 'top', $successMessage = "GeneralActionSuccessful", $successAnchor = 'top')
{
foreach ($validation as $key=>$value) {
// trim the string before validation
trim($validation[$key]['value']);
if($value['required'] == true && !$value['value']) {
$this->error = "ErrorFieldMissing";
$this->anchor = $failAnchor;
$this->formFields = $validation;
return;
}
switch($value['type']) {
case 'email':
if(!filter_var($value['value'], FILTER_VALIDATE_EMAIL)) {
$this->error = "ErrorInvalidEmail";
$this->anchor = $failAnchor;
$this->formFields = $validation;
return;
}
break;
}
}
// success, call the function passed
$function();
$this->success = $successMessage;
$this->anchor = $successAnchor;
}
Basically, what this does, is the controller calls the model validateInput()
method while passing the list of data for validation as a reference. An anonymous callback function, which also uses the same validation input by reference, is then called in the model. This way, no matter how the validator deals with the input array, the function behaves accordingly.
Please note that I only have email validation set up right now, because I don't need anything else. I just need to know if I'm doing things right, or if there's something I should re-learn.