Formlar görünümlerden türeyen bir yapıdır. Ancak kendi içinde CSRF token kontrolü gibi genişletilmiş özellikleri vardır.
Yeni bir form oluşturmak için oluşturulan form sınıfının \Src\Form\Form sınıfından türetilmesi gerekmektedir.
Bu sınıf soyut bir sınıftır ve aşağıdaki 3 metodun sınıf içinde tanımlanması gerekmektedir.
abstract public function getFormId(): string; // Formun özel kimliğini belirten bir string gönderilmelidir. CSRF jetonu için
abstract public function validate(): bool; // Form gönderildiğinde gelen değerlerin doğruluğu burada kontrol edilmelidir.
abstract public function submit(); // Form kontrolleri doğru olduğunda yapılacak işlem burada tanımanmalıdır.
<?php
namespace Src\Form;
use CoreDB\Kernel\ConfigurationManager;
use CoreDB\Kernel\Messenger;
use Src\Entity\ResetPassword;
use Src\Entity\Translation;
use Src\Entity\User;
use Src\Form\Widget\InputWidget;
class ForgetPasswordForm extends Form
{
public string $method = "POST";
private ?User $user = null;
public function __construct()
{
parent::__construct();
$this->addClass("user");
$this->addField(
InputWidget::create("email")
->setType("email")
->setLabel(Translation::getTranslation("email"))
->addClass("form-control-user")
->addAttribute("placeholder", Translation::getTranslation("email"))
->addAttribute("required", "true")
);
}
public function getFormId(): string
{
return "forget_password_form";
}
public function getTemplateFile(): string
{
return "forget-password-form.twig";
}
public function validate(): bool
{
$userClass = ConfigurationManager::getInstance()->getEntityInfo("users")["class"];
if (!$userClass::getUserByEmail($this->request["email"])) {
$this->setError("username", Translation::getTranslation("wrong_email"));
} else {
$this->user = $userClass::getUserByEmail($this->request["email"]);
if ($this->user->status->getValue() == User::STATUS_BANNED) {
$this->setError("username", Translation::getTranslation("account_banned"));
}
}
return empty($this->errors);
}
public function submit()
{
$reset_password = new ResetPassword();
$reset_password = ResetPassword::get(["user" => $this->user->ID]);
if (!$reset_password) {
$reset_password = new ResetPassword();
$reset_password->user->setValue($this->user->ID);
$reset_password->key->setValue(hash("SHA256", \CoreDB::currentDate() . json_encode($this->user->ID)));
$reset_password->save();
}
$reset_link = BASE_URL . "/reset_password/?USER=" . $this->user->ID . "&KEY=" . $reset_password->key;
$message = Translation::getEmailTranslation("password_reset", [$reset_link, $reset_link]);
$username = $this->user->getFullName();
\CoreDB::HTMLMail($this->user->email, Translation::getTranslation("reset_password"), $message, $username);
\CoreDB::messenger()
->createMessage(
Translation::getTranslation("password_reset_mail_success"),
Messenger::SUCCESS
);
}
protected function csrfTokenCheckFailed()
{
}
}
{% extends "forms/form.twig" %}
{% block messages %}
<h1 class="text-dark mb-3 text-center">{{ t("forgot_password_question") }}?</h1>
<div class="w-100">
{% for error in form.errors %}
{{ error }}
{% endfor %}
</div>
{% endblock %}
{% block fields %}
{{ form.fields["form_id"] }}
{{ form.fields["form_build_id"] }}
{{ form.fields["form_token"] }}
<div class="mb-3">
{{ form.fields["email"] }}
</div>
<div class="mb-3">
<button type="submit" class="btn btn-primary btn-lg w-100" name="reset">
<span class="fw-bolder">{{ t("reset") }}</span>
</button>
</div>
<hr/>
<div class="text-center">
<a class="link-primary fs-6 fw-bolder" href="{{ constant("BASE_URL") ~ "/login" }}">
{{ t("login") }}</a>
</div>
{% endblock %}