Jump to content

FrontendForms - A module for creating and validating forms on the frontend


Juergen

Recommended Posts

If you want to check your max upload file size, please add this code to your template:

echo ini_get("upload_max_filesize");

This will output the value as set inside your php.ini file.

You can see the line of code inside the InputFile.php: https://github.com/juergenweb/FrontendForms/blob/main/Formelements/Inputelements/Inputs/InputFile.php#L41

  • Like 1
Link to comment
Share on other sites

Thanks @Juergen it worked!

My other question is, if there is an option for unique filenames. I would like to use the form for submission. If someone uploads a file with the image.jpg, this file would be overwritten if someone else uploads another image with the same filename (image.jpg).

Maybe something like this would help?

$base = $pathinfo["filename"];
$filename = $base . "." . $pathinfo["extension"];
$destination = __DIR__ . "/uploads/" . $filename;

$i = 1;

while(file_exists($destination)) {
    
    $filename = $base . "($i)." . $pathinfo["extension"];
    $destination = __DIR__ . "/uploads/" . $filename;

    $i++;
}

 

Link to comment
Share on other sites

Hello @ngrmm

Interesting aspect I have not thought of before ?!

I am afraid, but there is no inbuilt method to prevent this.

I am thinking of a creating a new validator (fe uniqueFilename) to check if there is a file with the same name present inside the given directory. If so the validator should throw an error.

Maybe another possibility would be to add a new method to the file upload class (fe $field->renameDuplicates()), which renames duplicates by adding fe a number after the filename (fe. filename, filename-1, filename-2,...)

What do you think?

 

  • Like 1
Link to comment
Share on other sites

1 hour ago, Juergen said:

Maybe another possibility would be to add a new method to the file upload class (fe $field->renameDuplicates()), which renames duplicates by adding fe a number after the filename (fe. filename, filename-1, filename-2,...)

I'm not an expert ? but this sounds good.
 

And another issue I had was this:
I generate a page with the values of the submitted form. The filenames get sanitized after submitting. An uploaded Image.jpg is saved as image.jpg.
So in order to save add the files uploaded to a page, you have to sanitize them. Because the values-array has the original filenames

 

I did it this way:

	if($form->isValid()){

		$p = new Page(); // create new page object
		$p->template = 'template_name'; // set template
		$p->parent = $pages->get(1111); // set the parent
		$p->name = $sanitizer->pageName($form->getValue('surname'), true); // give it a name used in the url for the page
		$p->title = $form->getValue('textField'); // set page title
				
		$p->save();
		$p->addStatus('unpublished');

		foreach($form->getValue('fileuploads') as $fileItem) {
			//
			// sanitizing
			// $sanitizer->fileName() did not work for me :(
			//
			$sFile = $sanitizer->pageName($fileItem, true);
			$p->images->add("https://domain.com/site/assets/files/{$page->id}/{$sFile}");
		}
		
		$p->save();
	}

Maybe it be an option in the future to output the url of the image inside the values fieldarray?

  • Like 2
Link to comment
Share on other sites

@ngrmm

Please update to 2.1.58 - this version should fix your problems.

Please add the new validator to your fileupload field:

$fileuploads->setRule('uniqueFilenameInDir', true);

The following method

$form->getValue('fileuploads') 

should now show the sanitized and/or overwritten filenames as well.

The full explanation of the additions can be read here in the Changelogs.

 

As always, please take care if everything works as expected after the update!! ?

 

 

  • Like 1
  • Thanks 1
Link to comment
Share on other sites

Just a hint:

$form->getValue('fileuploads')

will output only the filenames.

If you need the path to the filenames too, you can use the following method:

$form->getUploadedFiles()

Best regards

  • Like 1
  • Thanks 1
Link to comment
Share on other sites

  • 1 month later...
<?php
namespace Processwire;

$contact_form = $pages->get("template=contact");
$company = $pages->get("template=company");

$form = new \FrontendForms\Form('Form');
$form->setHtml5Validation(true); // Enable HTML5 browser validation

// First Name
$firstname = new \FrontendForms\InputText('scf_firstname');
$firstname->setLabel($fields->get('scf_firstname')->$label);
$firstname->setRule('required');
$form->add($firstname);

// Last Name
$lastname = new \FrontendForms\InputText('scf_lastname');
$lastname->setLabel($fields->get('scf_lastname')->$label);
$lastname->setRule('required');
$form->add($lastname);

// Phone
$phone = new \FrontendForms\InputText('scf_phone');
$phone->setLabel($fields->get('scf_phone')->$label);
$phone->setRule('required');
$form->add($phone);

// Email
$email = new \FrontendForms\InputText('scf_email');
$email->setLabel($fields->get('scf_email')->$label);
$email->setRule('required');
$form->add($email);


// SERVICES
$service = new \FrontendForms\Select('scf_service');
$service->setLabel(__($fields->get('scf_service')->$label));
// Add options dynamically based on existing pages
$services = wire('pages')->find('template=insurance|telephony|pension, sort=name');

// Add options dynamically based on existing pages
foreach ($services as $servicePage) {
    $service->addOption($servicePage->title, $servicePage->id);
} 

$form->add($service);
    
$message = new \FrontendForms\Textarea('scf_message');
$message->setLabel($fields->get('scf_message')->$label);
$message->setRule('required');  
$form->add($message);

$button = new \FrontendForms\Button('submit');
$button->setAttribute('value', $fields->get('label_send')->label);
$button->setAttribute('class', 'btn btn-primary'); // Add the CSS class
$form->add($button);

if($form->isValid()){
    
    $p = new Page();
    $p->template = 'contact_inquiry';
    $p->parent = wire('pages')->get('template=contact');
    $p->title = $form->getValue('scf_firstname') . ' ' . $form->getValue('scf_lastname');
    $p->scf_firstname = $form->getValue('scf_firstname');
    $p->scf_lastname = $form->getValue('scf_lastname');
    $p->scf_phone = $form->getValue('scf_phone');
    $p->scf_email = $form->getValue('scf_email');
    $p->scf_service = $form->getValue('scf_service');
    $p->scf_message = $form->getValue('scf_message');
    
  
    // Set the scf_date field to the current date and time with the correct timezone
    $dateTime = new \DateTime('now', new \DateTimeZone('Europe/Stockholm'));
    $p->scf_date = $dateTime->format('Y-m-d H:i:s');
    
    $p->save();
    
    
    // Retrieve the title of the selected legal service
    $selectedserviceID = $form->getValue('scf_service');
    $selectedservice = wire('pages')->get($selectedserviceID);
    $selectedserviceTitle = $selectedservice ? $selectedservice->title : 'Not specified';
    
    
    
    // Initialize $messageBody
    $messageBody = '';
    
    $m = wireMail();
    $m->to('test@gmail.com');
    $m->subject("{$contact_form->scf_email_title} {$selectedserviceTitle}, {$form->getValue('scf_firstname')} {$form->getValue('scf_lastname')}");

    // Set "Reply-To" address
    $m->header('Reply-To', $form->getValue('scf_email') . ' (' . $form->getValue('scf_firstname') . ' ' . $form->getValue('scf_lastname') . ')');
  
    $messageBody .= "<strong>{$fields->get('scf_firstname')->label}:</strong> " . $form->getValue('scf_firstname') . "<br>";
    $messageBody .= "<strong>{$fields->get('scf_lastname')->label}:</strong> " . $form->getValue('scf_lastname') . "<br>";
    $messageBody .= "<strong>{$fields->get('scf_phone')->label}:</strong> " . $form->getValue('scf_phone') . "<br>";
    $messageBody .= "<strong>{$fields->get('scf_email')->label}:</strong> " . $form->getValue('scf_email') . "<br><br>";
    
    
    
    $messageBody .= "<strong>{$fields->get('scf_service')->label}:</strong> " . $selectedserviceTitle . "<br><br>";
    
    $messageBody .= "<strong>{$fields->get('scf_message')->label}</strong><br>" . $form->getValue('scf_message') . "<br>";
    
    $m->bodyHTML($messageBody);
    $m->send();
    
    
    
    // Set up the email for the form submitter
$confirmationEmail = wireMail();
$confirmationEmail->to($form->getValue('scf_email'));
$confirmationEmail->subject("{$contact_form->scf_email_confirmation_title} {$selectedserviceTitle}");

$confirmationMessage = "{$contact_form->scf_email_confirmation_message}";

$confirmationEmail->bodyHTML($confirmationMessage);
$confirmationEmail->send();
    
    
    
    
    // Redirect to the success page
    wire('session')->redirect(wire('config')->urls->root . 'arendet-skickades/');
}


echo $form->render();
?>

When i insert like XX into the email field there is an error Error: Exception: Invalid email address (in E:\Wamp\www\website\wire\core\WireMail.php line 162). I dont know how to validate the email adress before sending the form. Any clues?

Link to comment
Share on other sites

Hello @Flashmaster82

2 hours ago, Flashmaster82 said:
// Email
$email = new \FrontendForms\InputText('scf_email');
$email->setLabel($fields->get('scf_email')->$label);
$email->setRule('required');
$form->add($email);

You have only added the required Validator. There are a lot of examples inside the examples folder how to validate an email address (fe at the contact forms).

In this folder you will also find a special file with a lot of validation examples: https://github.com/juergenweb/FrontendForms/blob/main/Examples/field-validation.php. This file contains examples of (nearly) all possible validators and how to add them to an input field.

There are 2 special validators for validation of an email, which are interesting for you:

 

In the next steps I will show you 3 possibilities (option) how to validate an email field.

Option 1: Add the additional email validators to your code example

// Email
$email = new \FrontendForms\InputText('scf_email');
$email->setLabel($fields->get('scf_email')->$label);
$email->setRule('required');
$email->setRule('email'); // checks for the right syntax of the email
$email->setRule('emailDNS'); // optional: checks if the email has a valid DNS record
$form->add($email);

This works, but it is not the recommended way for emails. You have used an InputText input field, but for emails there is a special input field, which includes the mentioned validators by default: InputEmail

Option 2: Instead of using InputText, it is better to use InputEmail, which includes email valdiation by default

// Email
$email = new \FrontendForms\InputEmail('scf_email'); // make usage of InputEmail 
$email->setLabel($fields->get('scf_email')->$label);
$email->setRule('required');
$form->add($email);

As the last option, I want to show you a pre-defined email input. To simplify life, I have created pre-defined input field types for the most used form fields, like surename, lastname, email, message and so on. You will find all this pre-defined fields inside the defaulf folder.

These default fields includes validators and labels for these inputfields and the code is very short.

Option 3: This code includes all email validators and the pre-defined email label - it is the shortest version.

// Email
$email = new \FrontendForms\Email('scf_email');
$email->setRule('required');
$form->add($email);

Now you have 3 options, where you can choose from.

Best regards Jürgen

  • Like 2
Link to comment
Share on other sites

Thanks for the fast and great reply.
 

// Email
$email = new \FrontendForms\InputEmail('scf_email'); // make usage of InputEmail 
$email->setLabel($fields->get('scf_email')->$label);
$email->setRule('required');
$form->add($email);

I think this made the trick!!

  • Like 1
Link to comment
Share on other sites

  • 4 weeks later...

Hi.
Today I installed your module on latest DEV PW
HW is FreeBSD14, PHP 8.3.1(PHP-FPM), MySQL8.1, 32GB RAM, 8-core CPU
After install of your module RAM of server was suddenly from 10% to 95% and whole system was unstable.
Do you have any problems with your module like this ?
Is PHP 8.3.1 supported ?
Thanks for answer
Pavel

Link to comment
Share on other sites

Hello @PavelRadvan

Thanks for your info at first. I have not discovered problems like this til now and I guess other users do not run into problems like this too. Otherwise someone has informed me about such a behavior.

I only run this module on PHP 8.1, but there I have no problems at all. The code should run on 8.3 too, but I have only tested the syntax on PHP-Storm and not in live situation - so the code should be valid for PHP 8.3 too.

Some question:

Does the problem consist on every page request?

Do you have tried to close all browser windows and open the website after that again (sometimes PW runs into performance issues, with an unknown issue and after "re-start" everything works as expected)?

Does this problem persists if you are calling only the backend (without forms output on the frontend).

Maybe you could give me some infos about that.

Best regards Jürgen

 

 

Link to comment
Share on other sites

52 minutes ago, Juergen said:

Hello @PavelRadvan

Thanks for your info at first. I have not discovered problems like this til now and I guess other users do not run into problems like this too. Otherwise someone has informed me about such a behavior.

I only run this module on PHP 8.1, but there I have no problems at all. The code should run on 8.3 too, but I have only tested the syntax on PHP-Storm and not in live situation - so the code should be valid for PHP 8.3 too.

Some question:

Does the problem consist on every page request?

Do you have tried to close all browser windows and open the website after that again (sometimes PW runs into performance issues, with an unknown issue and after "re-start" everything works as expected)?

Does this problem persists if you are calling only the backend (without forms output on the frontend).

Maybe you could give me some infos about that.

Best regards Jürgen

 

 

Hi.

Thanks for you answer.
I did not have any chance to do more, because whole system had problem immediately after installation.
After I clicked on settings of your module, it was after few moments stuck in loading and loading......

So after circa 10 minutes I canceled all and restarted mysql and apache + php.
Then after login to administration of PW it happened again...
So finally I had to restart whole HW
I had to check configuration of mysql and reinstall it because there was some strange damage to its install...
In logs was only that MySQL shutted down and no extra info more...
What do you think of it ?
Pavel

 

 

 

 

Link to comment
Share on other sites

Thats a very strange behavior ? Are there some errore messages inside the logfiles of PW (maybe a time setout message)...

I have no idea, what the cause could be. As you write, this happens directly after you are trying to go to the settings page of the module..... but the only process, that runs in this case is the rendering process. So there must be something the stops this rendering process of the setting form.

Maybe it could have something to do with PHP 8.3 because PHP Storm complains about not declared variables inside the setting form for the module. The point is that the creation of the setting form of a module is done via PW API functions and therefore I do not have an influence here.

Please check your log files if something has been stored there. On the weekend I transfer a website to a server who uses 8.3. I will check this out to see if some problems occur.

Link to comment
Share on other sites

39 minutes ago, PavelRadvan said:

In logs was only that MySQL shutted down and no extra info more...

Ok, I have overread this before. At the moment I can only recommend you to wait until i have installed the module on the 8.3 server. I will give you an information about it. Eventually there are other forum members, which use 8.3 and have some experiences with it.

Link to comment
Share on other sites

Good Morning @PavelRadvan

Now I have tested the latest FrontendForms with the latest dev PW version on a  live test server after upgrading to PHP 8.3.1 and in my case it works without problems.

phptest.thumb.jpg.4c9b4a0406e83cf40bc90de5a1353b39.jpg

So I can confirem, that there is no problem using FrontenForms with PHP 8.3.1. Maybe your problems are caused by a misconfiguration of the server? But without getting error messages it is difficult to trace the problem to its source. I use it on a shared host and I do not make any changes to the server (and I am not an expert at servers).

Best regards Jürgen

Link to comment
Share on other sites

  • 1 month later...
Posted (edited)

Hi @Juergen

I try test your best module with PHP 8.3.18

And I found some mistake. It happened when I wanted to see the details of a blocked address.

 

scr.jpg

System env

image.png.80d848141f513ceac7ea68f67469dfdf.png

Edited by Andy
  • Thanks 1
Link to comment
Share on other sites

Hello @Juergen

Thanks for the quick response. Yes, this feature now is working.

But I immediately have a question - how to remove some IP from this list?

I am testing your module now and see what a great job you have done. I will try to help you with debugging.

Another problem occurred when updating your module.

Warning: copy(/var/www/htdocs/minotaur/htdocs/captchaimage.php): Failed to open stream: Permission denied in /var/www/htdocs/minotaur/htdocs/wire/core/WireFileTools.php on line 282

I have the root folder locked from writing. That's not safe. Are you sure that captchaimage.php should be in the root folder?

Another small find. In example /site/modules/FrontendForms/Examples/contactform.php 

$accept = new \FrontendForms\InputCheckbox('accept');
$accept->setLabel('I accept the data privacy');
$accept->setRule('required')->setCustomMessage('You have to accept the data privacy');
$accept->setRule('accepted');
$form->add($accept);

$accept->setRule('accepted'); Incorrect construction. You must use a different function for checked.

$accept->setChecked();

Best regards.

Yours Andy

  • Like 1
Link to comment
Share on other sites

Posted (edited)

Hello @Andy

Thank you for your extensive feedback ?!!!

11 hours ago, Andy said:

But I immediately have a question - how to remove some IP from this list?

I am not sure, which list you are talking about. There is the "Blacklist" of IP addresses, that should be banned in first instance. You will find this list inside the security tab.

1341076479_Screenshot2024-05-16at06-30-44ModuleFrontendFormsschulfreund_at.thumb.png.9fbd377fd3db5cefba62befc14aae01c.png

There you can delete the entries as usual.

The other list is the list of entries for failed attempts (I guess you are talking about this list). This list is stored as a logfile.

756448214_Screenshot2024-05-16at06-33-55LogsProcessWireschulfreund_at.thumb.png.d611225e857bbe477cc652a0d6d9b960.png

This logfile can be found under "Setup/logs" and has the name "Failed-attempts-frontendforms". You can delete the whole log file, but you cannot remove only a certain entry in it. I think there would not be a benefit, if you are able to delete only certain entries.

11 hours ago, Andy said:

I have the root folder locked from writing. That's not safe. Are you sure that captchaimage.php should be in the root folder?

Not really! The place for the captcha.php must be a place that is public reachable and the execution of files must be allowed. At the time of writing of this module, I wanted to place this file inside the assets folder. But there was a problem: The access folder is public reachable, but PHP files were not allowed at this time, because they are executable. So I put in inside the root.

I can remember that there was a discussion in the forum about this restriction. I am not sure, but maybe nowadays it could be possible to use PHP files inside the assets folder (must be tested).

I think your issue is it worth to think about it to place the captcha.php inside a custom folder (or inside the assets folder if it is allowed).

11 hours ago, Andy said:

$accept->setRule('accepted'); Incorrect construction. You must use a different function for checked.

I have taken a look inside the contactform.php file, but I have not found it ?

I have deleted it inside the contact.php!

But you are right - to test if a checkbox is checked, you only need to add the"required" validator". The other validation rule is not valid.

11 hours ago, Andy said:

$accept->setChecked();

This is not a validator -> it sets the checkbox to checked on form load. You can use this to mark a checkbox by default. But it should not be used in combination with the data privacy check, because the user should mark this box and it should not be marked before. ?

I will try to fix the problem with the root, because this is a serious issue, but it could not be done within an afternoon. So please be patient!

Thanks for all your efforts and have a nice day!

Jürgen

Edited by Juergen
Removing wrong sentence
  • Like 1
Link to comment
Share on other sites

Hello @Juergen

Thank you for your quick and complete response.

Regarding the captchaimage.php file. I think we should add a couple of lines about this in the Quick Start documentation section.

"During installation, you will need to write the captchaimage.php file to the root folder. You can change permissions on this folder for the time of module installation. Or write the captchaimage.php file to the root folder and allow the system to update it."

Another way is to change the functionality of the module installer. Check if it is possible to write captchaimage.php to the root folder. And if it is not possible, send a message to the user: "No access to root folder. Move the file /site/modules/FrontendForms/Formelements/Captcha/captchaimage.php to the root folder yourself."

Yours Andy

  • Like 1
Link to comment
Share on other sites

2 minutes ago, Andy said:

"During installation, you will need to write the captchaimage.php file to the root folder. You can change permissions on this folder for the time of module installation. Or write the captchaimage.php file to the root folder and allow the system to update it."

I think this sounds interesting, because the user does not have to take care about it and the installation process is the same. I will take a look at how this could be done.

Thanks

  • Like 1
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...