createAndSetupElement( 'form', '', [ 'method' => 'post', 'action' => '', ] ); // LABEL NAME $label_name = $this->createAndSetupElement( 'label', $this->loadTextFile(Resolve::arrayToId([ $this->getLanguage(), 'name' ])), [ 'for' => 'name', ] ); $form->appendChild($label_name); // NAME INPUT $name = $this->createAndSetupElement( 'input', '', [ 'id' => 'name', 'name' => 'name', 'type' => 'text', 'value' => $_POST['name'] ?? '', ] ); $form->appendChild($name); // LABEL Email $label_email = $this->createAndSetupElement( 'label', $this->loadTextFile(Resolve::arrayToId([ $this->getLanguage(), 'email' ])), [ 'for' => 'email' ] ); $form->appendChild($label_email); // EMAIL INPUT $email = $this->createAndSetupElement( 'input', '', [ 'id' => 'email', 'name' => 'email', 'type' => 'email', 'value' => $_POST['email'] ?? '', ] ); $form->appendChild($email); // LABEL Message $label_message = $this->createAndSetupElement( 'label', $this->loadTextFile(Resolve::arrayToId([ $this->getLanguage(), 'message' ])), [ 'for' => 'message' ] ); $form->appendChild($label_message); // MESSAGE INPUT $message = $this->createAndSetupElement( 'textarea', $_POST['message'] ?? '', [ 'id' => 'message', 'name' => 'message', ] ); $form->appendChild($message); // LABEL Captcha $label_captcha = $this->createAndSetupElement( 'label', '', [ 'for' => self::KEY_CAPTCHA_PHRASE ] ); $label_captcha->appendChild($this->generateCaptcha()); $form->appendChild($label_captcha); // CAPTCHA INPUT $captcha = $this->createAndSetupElement( 'input', '', [ 'id' => 'captchainput', 'name' => self::KEY_CAPTCHA_PHRASE, 'type' => 'text', ] ); $form->appendChild($captcha); // SUBMIT BUTTON $submit = $this->createAndSetupElement( 'button', $this->loadTextFile(Resolve::arrayToId([ $this->getLanguage(), 'submit' ])), [ 'id' => 'submit', 'type' => 'submit', ] ); $form->appendChild($submit); // ADD CSRF CHECK $form->appendChild($this->generateCsrfInput()); return $form; } private function generateCsrfInput() { // create token and save to session $token = bin2hex(random_bytes(6)); $this->getSession()->set(self::KEY_CSRF_TOKEN, $token); return $this->createAndSetupElement( 'input', '', [ 'type' => 'hidden', 'name' => self::KEY_CSRF_TOKEN, 'value' => $token, ] ); } private function validateCsrfInput() : bool { if (!$this->formSubmitted()) { return true; } $token = $this->getSession()->get(self::KEY_CSRF_TOKEN); if ( is_null($_POST[self::KEY_CSRF_TOKEN]) || $_POST[self::KEY_CSRF_TOKEN] !== $token ) { return false; } return true; } private function generateCaptcha() { $builder = new CaptchaBuilder(); $builder->build(); $this->getSession()->set(self::KEY_CAPTCHA_PHRASE, $builder->getPhrase()); $img_captcha = $this->createAndSetupElement( 'img', '', [ 'id' => 'captcha', 'src' => $builder->inline(), ] ); return $img_captcha; } private function validateCaptcha() : bool { if (!$this->formSubmitted()) { return true; } $valid_phrase = $this->getSession()->get(self::KEY_CAPTCHA_PHRASE); if ( is_null($_POST[self::KEY_CAPTCHA_PHRASE]) || $_POST[self::KEY_CAPTCHA_PHRASE] !== $valid_phrase ) { return false; } return true; } private function formSubmitted() { return ( !is_null($_POST['name']) || !is_null($_POST['email']) || !is_null($_POST['message']) ) ? true : false; } public function run(array $options = []) : bool { if (!$this->validateCsrfInput()) { $this->getSession()->getFlashBag()->add( 'error', $this->loadTextFile(Resolve::arrayToId([ $this->getLanguage(), 'flashmessages', 'error', 'csrf-failed' ])) ); } if (!$this->validateCaptcha()) { $this->getSession()->getFlashBag()->add( 'error', $this->loadTextFile(Resolve::arrayToId([ $this->getLanguage(), 'flashmessages', 'error', 'captcha-failed' ])) ); } $form = $this->createForm(); $this->appendChild($form); return true; } public function onWebsocketRequest( \Lewp\Websocket\Message $message ) : \Lewp\Websocket\Message { } };