Search the Community
Showing results for 'WireMail'.
-
I have never come across with before — especially odd as I use this hosting company for scores of ProcessWire sites but I am having issues with email sending. I am just using normal WireMail() and this works in about 95% of my sites so I don't need to set up a separate SMTP account. The hosting company is claiming in this instance is it because the PW module is not setting the -f $from_address in PHP mail()'s $additional_params paramater. (I am using LoginRegisterPro and the email in question is the confirmation one. I guess this is irrelevant since LRP will use whatever mail module PW is set to use.) Anyway, can I set the -f flag in mail() without hacking the PW core code? Thanks.
-
RockShell - a ProcessWire Commandline Companion ⌨️
Jonathan Lahijani replied to bernhard's topic in Modules/Plugins
Tip: In Symfony Console, if you run code and an Exception or WireException occurs, ProcessWire will not be able to log it (and also send an adminEmail). There were cases where I was calling an undefined method on a page object and not knowing about it erroring. I used AI to work through this and ultimately it said I have to basically manage this myself because Symfony Console will catch things if I don't and never hit ProcessWire. Therefore, you may want to do something like this in your handle method: public function handle() { try { nonExistentFunction(); // purposely cause an error } catch (\Throwable $e) { // log the error $this->wire()->log->save('errors', $e->getMessage()); // consider adding additional code here to send an email notification using WireMail // ... // Re-throw so it still displays in console throw $e; } return self::SUCCESS; } I wonder if there's a more efficient way to do this? It took me too long to figure out what was happening in the first place so I haven't spent time optimizing the approach (if it's even possible). -
Hello! I want to find out if this plugin is able to take over all mail sending within ProcessWire automatically by simply replacing the default WireMail Class. If so, where can I configure "SMTP via OAuth" like it is described here: https://github.com/PHPMailer/PHPMailer/wiki/Microsoft-Azure-and-XOAUTH2-setup-guide Is that even possible, or do I have to manually go through all my websites forms and send the mail programmatically? Luckily, I do have all the Azure Application-IDs and secret codes right here, but where do I fill them in?
-
No, but I think there must be another cause than I have thought first. The strange thing is that I can send mails by using 2 of my modules with the WireMail class without problems on that host. Only the third module makes problems. I have solved this problem for now by using the WireMailSmtp module.
-
Hello at all I encountered a strange issue when sending emails using the Wiremail class from a shared host (world4you.com). Short description of the problem I added the following code from the documentation for the WireMail class to one of my templates for testing purposes: $m = $mail->new(); $m->to('myemailadress@example.at') // will be replaced with my real mail addy ->from('testmail@test.at') ->subject('Message Subject') ->body('Optional message body in plain text') ->bodyHTML('<html><body><p>Optional message body in HTML</p></body></html>') ->send(); After loading a page with this template, the email should be sent to my email address, but I never receive an email. If I use the same code on my local Installation with XAMPP using Gmail as my mail Client everything works as expected. So I tried to figure out where the problem might be, and I discovered the following: The WireMail class contains the send() method, which is responsible for sending the email. There you will find the PHP mail function, which contains a header variable ($header). If I remove this header variable from the brackets, the email is sent; otherwise, it is not. But the email content will not be displayed properly without this header variable. Before removing the header variable: if(@mail($to, $subject, $body, $header)) $numSent++; After: if(@mail($to, $subject, $body)) $numSent++; The problem could therefore be due to an incorrect header. So I took a look at the function renderMailHeader() which is responsible for creating the mail header syntax. I found out that the email is only sent if the value of “From” in the header is enclosed in double quotation marks, otherwise it will not be sent (see figure below). This does not seem to be important on my local installation. By default, the "From" value (in this case "myemail@example.com) is not between quotes in the header. If I change this inside the renderMailHeader() function, the mail will be sent. Only to mention: There is no entry in the log files indicating that something went wrong. Does anyone else have the same problem on a shared host and know how to fix it? I don't want to use SMTP instead, though. I guess there must be a better solution than changing something in the code or the problem is not the header syntax. Perhaps the header is not the problem, but rather the problem is related to something else?!? Thanks in advance for your help and hints
-
Hi everyone, I tried a lot, but I don´t know if I´m on the right track. I hope, someone can help. I store orders in pages. Every order has a FileField "invoice_pdf". To prevent public access to the PDF, the page template has a pagefileSecure setting and no viewing rights for guest role. The files are then saved unter /site/assets/files/-XXXX/ -> the - prefix is part of the pagefileSecure setting, I guess. Now I want to send the PDF as mail attachment to my customer. But the PDF->url / PDF->httpURL() contains the path without the - prefix. The mail is sent without attachment. I guess because the real path doesn´t countain a file. Is it possible, to send attachment-files, uploaded to a pagefileSecure field? Thanks a lot for your help!
-
Btw, if there are modules or hooks that send only plain text emails like for example some notifications on LoginRegisterPro with the following hook you can force HTML on all outgoing emails and forget about those ugly emails 😎 /** * Force HTML on all outgoing emails * */ $wire->addHookBefore('WireMail::send', function(HookEvent $event) { $wireMail = $event->object; if($wireMail->body && !$wireMail->bodyHTML) { $forceHTML = nl2br($wireMail->body); // nl2br — Inserts HTML line breaks before all newlines in a string $wireMail->bodyHTML($forceHTML); } }); I guess this can get combined with your hook but for now I'm using it as separate.
-
If you can, maybe try temporarily disabling Login Register Pro to default to the standard PW login mechanism. Use the PHP code-based password reset trick for a specific account that only you have access to, and see if you're able to successfully login. If you're able to log in, you may need to check the (WireMail) email settings on the new host, as well. If that works, try re-enabling Login Register Pro and see if that now works. If not, you might need to post in the Pro support forum for that module. (I don't use it, so I'm not sure what to suggest.)
-
How to use WireMail SMTP module with Oauth 2
DrQuincy replied to DrQuincy's topic in General Support
Do you know how to hook into WireMail so I can set this manually? I thought it was based on Swift but I just read that's discontinued now. I'd be able to get it working with Swift but I need it to use WireMail for LRP, EmailNewUser, etc to work. -
I'm using SMTP successfully with Google and an app password for other clients. A client has a custom stricter setup and they say they can only use SMTP with Oauth2. I presume this will involve regularly generating access tokens. Is there any way to make this work with the WireMail SMTP module? There is nothing in the settings. I need it to work at a global level so all $mail routes through this since I am using the LoginRegisterPro and EmailNewUser modules. Thanks.
-
Hey @marie.mdna sorry for the delay. I was sick and had to have some days off the computer 🙂 Thx! And thx for your question! The answer to these kind of questions is probably always the same: Yes and no. Yes, you can for sure build such a scenario. No, not out of the box. It's similar as if you asked "does ProcessWire support selling digital goods?" RockCommerce tries to be a good foundation for selling anything online and using ProcessWire to manage all the data. So it will handle the basics for you that are the same for any store that I can think of (meaning handling orders, for example), but everything else usually has to be built by the developer. With product variations being one exception as not every store might need it, but if it does, it would be an absolute nightmare to have to build it on your own. So to answer your question: Just have a look at my website - I'm doing exactly that! You can buy my modules there. Once you buy one, the store sends you an email with the license key. The mail is sent by WireMail, the logic for the license key is built on my own. The invoice is created using RockPdf. The thing is: Every shop is different. Every business is different. How long is a license valid? What does it allow? Etc, etc. I tried to provide a good foundation that saves you a lot of time and makes a lot possible with the least possible effort. Just like ProcessWire does with the $page magic and the admin interface to manage content. Does that make sense? The great thing about RockCommerce is that when using it, you have all your data in ProcessWire. You control that data, you define its structure. And you can easily add your own business logic on top of it - exactly like you want. So many things are just some lines of ProcessWire API away 🙂 But that also means that you might have to build that logic on your own, that other shops might already have built in. In the way they think is best, of course 😉 Which might fit your needs or not... I have added this to the docs: https://www.baumrock.com/en/processwire/modules/rockcommerce/docs/checkout/
-
Hey @Cybermano glad it was helpful! That's what I've been using before I had the idea of hooking into WireMail::send. Everything in life has pro's and con's... So I'd not say it's a bad practise. But what I like about the solution is that it fits my credo "simple things should be simple". Sending a beautiful thing should be simple. And what you show might look QUITE simple it's not as simple as my version. If you only have one mail it won't matter or your version would even be easier (because you see everything that is going on). But if you are sending mails from different places in different occasions (eg on registration, on a new post, on a schedule, etc...) then my version keeps your code DRY (don't repeat yourself) whereas your version either tempts the dev to copy and paste those lines of code or be too lazy and just send out an ugly 90s style email. Both is not ideal in my opinion and investing a little more time to setup the hook will be beneficial in the long run. Also, while it's just a few lines of code, when your codebase grows every line of code that is not instantly and easily understandable matters. Your brain has to read the code, understand it, interpret it and remember it. With your str_replace that might be QUITE easy, but things add up and suddenly it might make the difference between easy to read code and a bloat of spaghetti code. It's about building a habit. Another problem with your solution is that if you copy&paste this to 3 spots, for example, and later you add another replacement tag, you have to do a search&replace and you might miss one spot and you introduce a bug. If you have it on a central place this can not happen. On the other hand if you want to render different files or you want different tags for different emails your approach might be the better one. And for someone not familiar with your codebase it might be easier to understand your version vs. the hook, because only seeing the $mail->send() somewhat hides how the mail gets sent with nice HTML and your version makes that obvious.
-
Turn Your Boring ProcessWire Emails into Beautiful Masterpieces! 🎨
Ellyot_Chase replied to bernhard's topic in Tutorials
Wow, really helpfull @bernhard! Thanks. Up until now i had an output buffer and included a template file, or rendered a page before my wiremail call to get an instance. But this will make things way cleaner. -
Ever felt like your ProcessWire emails look like they're stuck in 1999? You know the drill - sending emails is super easy with WireMail: $m = new WireMail(); $m->from('foo@bar.com'); $m->to('xxx@yyy.com'); $m->subject('Hello there!'); $m->bodyHTML('<h1>This is great!</h1><p>I am an ugly mail...</p>'); $m->send(); But let's be honest - they look about as pretty as a website built with Microsoft FrontPage! 😅 🪄 Enter the Mail Pimp Hook! Drop this magical hook into your /site/ready.php (or even better Site.module.php), and watch your emails transform from ugly ducklings into beautiful swans: <?php $wire->addHookBefore('WireMail::send', function(HookEvent $event) { // double check that we got a wiremail instance // this also tells the IDE what $mail is (to get IntelliSense) $mail = $event->object; if (!$mail instanceof WireMail) return; // get current mail body $html = $mail->get('bodyHTML'); if (!$html) return; // get email layout markup $layoutFile = wire()->config->paths->templates . 'mails/default.html'; if (!is_file($layoutFile)) return; // replace ##content## with actual mail content $html = str_replace( '##content##', $html, wire()->files->render($layoutFile) ); // write new body to mail $mail->bodyHTML($html); }); The HTML Just create a beautiful MJML template at /site/templates/mails/default.mjml, put ##content## where your email content should go, convert it to HTML and BOOM! 💥 Every email gets automatically wrapped in your gorgeous template. No more CSS wrestling matches, no more "Why does this look different in Outlook?" headaches. Just pure email beauty, automagically! ✨ Now your clients will think you spent days crafting those emails, when in reality, you're sipping coffee while your hook does all the heavy lifting. Work smarter, not harder! 🚀 #ProcessWire #EmailMagic #NoMoreUglyEmails PS: This is the MJML template that I used: <mjml> <mj-head> <mj-attributes> <mj-all font-family="Tahoma" /> <mj-text line-height="140%" /> </mj-attributes> </mj-head> <mj-body background-color="#efefef"> <mj-section background-color="#ffffff" background-repeat="repeat" padding-bottom="30px" padding-top="30px" text-align="center" > <mj-column> <mj-image align="center" padding="25px" src="xxx" target="_blank" width="200px" alt="Logo" ></mj-image> <mj-text>##content##</mj-text> </mj-column> </mj-section> <mj-section> <mj-column> <mj-text font-size="10px" color="#a0a0a0" align="center" > powered by <a href="https://www.baumrock.com/" style="color: #158f66" >baumrock.com</a > </mj-text> </mj-column> </mj-section> </mj-body> </mjml> VSCode has an extension to get a live preview and export MJML to HTML: And here are some other free templates: https://mjml.io/templates I use https://www.base64-image.de/ to add the logo to my mail template as src="data:image/jpeg;base64,/9j/4QAWRXhpZgAATU0AKgAAAA..." to avoid headaches with image paths, remote assets blocking etc.
- 14 replies
-
- 20
-
-
-
I'm almost done with my integration of this module, and it's working great. WireMail and WireMailSMTP integration was easy. I have 2 issues though: 1. On AJAX submission, the loading message "Please be patient... the form will be validated!" seems to be hard-wired. Would you be able to offer some way for developers to override it with their own custom text? For example, I'd like my site to simply show "Submitting your enquiry...". 2. Whenever I type into my textarea form field, my JavaScript console gives me this error: Uncaught TypeError: Cannot read properties of null (reading 'children') at HTMLTextAreaElement.<anonymous> (frontendforms.js?v=2.2.17:455:29) I think it's something to do with the character counter, which I have not enabled. And the form still submits OK. Thanks in advance for looking into these issues!
-
Hi, I'm stucked while using the mail sending, also the plugin WireMailSmtp is installed. $m = wireMail(); $m->to('test@example.com') ->header('bcc', 'asdf@example.com') //->from() ->subject( "HMTL | ") ->bodyHTML("DAs ist ein TÄÖÜ") ->send(); is creating the mail attached. I have no clue, but I also do not want to use phpmailer Any help is appreciated!
-
Hi, I don't have WireMailRouter and therefor don't know how it works together. But please can you (or @Ivan Gretsky or @wbmnfktr, who seems to have it too, like you) simply test the following OneLineChange in the WireMailSmtp-Testfunction? $mail = wireMail(); if ($mail->className != 'WireMailSmtp' && $mail->className != 'WireMailRouter) { .... It then will skip the abort. So, don't know if it then works like it should, but that's why I ask for the test. 🙂 Let me know if someone can do that, and if so, what was the result. Greetings! 🙋♂️
-
WireMailRouter was set to use WireMailSmtp as primary method, but (if a from and to is specified in verbose settings) WireMailSmtp ignores the test attempt if it is not the WireMail class name: $mail = wireMail(); if($mail->className != 'WireMailSmtp') { $dump = "<p>Couldn't get the right WireMail-Module (WireMailSmtp). found: {$mail->className}</p>"; } else { So basically the full test will not work if WireMailRouter is installed - only the plain connection test. My suggestions are: The config screen should make it clear that verbose debug settings will not work if WireMailSmtp is not the WireMail class and need to be empty to test the connection only, or that the test should temporarily set the WireMail class to be WireMailSmtp - something like: if($from && $to) { // do a verbose debugging if(!$subject) $subject = 'Debug Testmail'; if(!$body) $body = 'Debug Testmail, äöüß'; $mail = wireMail(); $dump = ''; if($mail->className != 'WireMailSmtp') { $wireMailClass = $mail->className; $this->config->wireMail('module', 'WireMailSmtp'); $mail = wireMail(); $dump .= "<p>Currently installed WireMail class is $wireMailClass. Testing with WireMailSmtp, then reverting to $wireMailClass.</p>"; } $mail->from = $from; $mail->to($to); $mail->subject($subject); $mail->sendSingle(true); $mail->body($body); $dump .= $mail->debugSend(3); if(isset($wireMailClass)) $this->config->wireMail('module', $wireMailClass); } else { // only try a testconnection Personally I'm more inclined to (2), but does anyone else have a view?
-
Minor request. Is it possible to use the 'test' function when wireMailRouter is installed? I get "Couldn't get the right WireMail-Module (WireMailSmtp). found: WireMailRouter" If I set $config->wireMail('module', 'WireMailSmtp'); temporarily then it works, but I wonder if it is possible for the module to supply that as an override when testing?
-
Hey guys, Microsoft is deactivating SMTP Basic Authentication at the end of the year. https://learn.microsoft.com/en-gb/exchange/clients-and-mobile-in-exchange-online/deprecation-of-basic-authentication-exchange-online Has anyone already found a solution to get Office365 working with OAuth 2.0? @ryan would it be possible to adapt your "WireMailGmail" module? Or maybe someone is knowledgeable enough to design a general OAuth wireMail module? ?
-
@Sanyaissues Thanks for reporting. I must admit, I'm stumped by this as the PHP looks OK to me - it's a simple string concatenation. Perhaps @ryan can chip in and let us know if the module loading code tries to find the PHP string by pattern matching on the text of the module file, rather than running the function - though I doubt that's the case. Anyway, could you try replacing the getModuleInfo() function with the following in the WiremailPostmark.module.php file... public static function getModuleInfo() { $php_version = 'PHP>=' . self::MIN_PHP; return [ 'name' => self::MYCLASS, 'title' => 'WireMail for Postmark', 'author' => 'Netcarver & Pete of Nifty Solutions', 'summary' => 'Allows Processwire to send transactional email via Postmark', 'href' => 'https://postmarkapp.com', 'version' => '0.5.3', 'autoload' => true, 'singular' => false, 'permanent' => false, 'requires' => [ 'ProcessWire>3.0.33', $php_version, ], ]; } ...and try reloading and installing the module? Please post a screenshot of the errors (if any). Also, what version of ProcessWire are you running? Thanks.
-
Hi, here is the new code for your contact form: <?php declare(strict_types=1); namespace ProcessWire; /* * File description * * Created by Jürgen K. * https://github.com/juergenweb * File name: contactform-2.php * Created: 15.02.2023 */ $content = ''; $form = new \FrontendForms\Form('contact'); $form->setMaxAttempts(0); // disable max attempts $contacttype = new \FrontendForms\InputRadioMultiple('auswahl'); $contacttype->addOption('Einzelperson (Jahresbeitrag 50,00 EUR)<span class="asterisk">*</span>', 'Einzelperson (Jahresbeitrag 50,00 EUR)')->setAttribute('data-value', '1'); $contacttype->addOption('Doppelmitgliedschaft (Jahresbeitrag 75,00 EUR)<span class="asterisk">*</span>', 'Doppelmitgliedschaft (Jahresbeitrag 75,00 EUR)')->setAttribute('data-value', '2'); $contacttype->alignVertical(); $contacttype->setRule('required')->setCustomMessage('Bitte wählen Sie die gewünschte Mitgliedschaft aus.'); $form->add($contacttype); // add the gender field $gender = new \FrontendForms\Gender('gender'); //$gender->setLabel('Auswählen'); // so Label setzen! $form->add($gender); // add the name field $name = new \FrontendForms\Name('firstname'); $name->setRule('firstAndLastname')->setCustomFieldName('Der Vorname'); $form->add($name); // add the surname field $surname = new \FrontendForms\Surname('lastname'); $surname->setRule('firstAndLastname')->setCustomFieldName('Der Nachname'); $form->add($surname); // check if $_POST value is present for "auswahl" and set "display" according to "auswahl" value $display = 'none'; if (wire('input')->post('contact-auswahl')) { $value = explode(' ', wire('input')->post('contact-auswahl')); if ($value != 'Einzelperson') { $display = 'block'; } } // add the name2 field $name2 = new \FrontendForms\InputText('firstname2'); $name2->setLabel('Vorname (zweite Person)'); $name2->setRule('firstAndLastname')->setCustomFieldName('Der Vorname der zweiten Person'); $name2->useCustomWrapper()->setAttribute('id', 'firstname-wrapper')->setAttribute('style', 'display:' . $display); $form->add($name2); // add the surname2 field $surname2 = new \FrontendForms\InputText('lastname2'); $surname2->setLabel('Nachname (zweite Person)'); $surname2->setRule('firstAndLastname')->setCustomFieldName('Der Nachname der zweiten Person'); $surname2->useCustomWrapper()->setAttribute('id', 'lastname-wrapper')->setAttribute('style', 'display:' . $display); $form->add($surname2); // Adresse $adresse = new \FrontendForms\InputText('adresse'); $adresse->setLabel('Straße und Hausnummer'); $adresse->setRule('required')->setCustomFieldName('Die Adresse'); $form->add($adresse); // plz $plz = new \FrontendForms\InputText('plz'); $plz->setLabel('Postleitzahl'); $plz->setRule('integer')->setCustomFieldName('Die Postleitzahl'); $plz->setRule('required'); $form->add($plz); // Ort $ort = new \FrontendForms\InputText('ort'); $ort->setLabel('Ort'); $ort->setRule('required')->setCustomFieldName('Der Ort'); $form->add($ort); // add the email field $email = new \FrontendForms\Email('email'); if ($user->isLoggedIn()) { $email->setDefaultValue($user->email); } $form->add($email); // add the phone field $phone = new \FrontendForms\Phone('phone'); $phone->setLabel('Telefon / Mobil'); $phone->setRule('required')->setCustomFieldName('Die Telefonnummer'); $form->add($phone); // add the Geburtstags field $geb = new \FrontendForms\InputText('geb'); $geb->setLabel('Geburtsdatum'); $form->add($geb); $einzug = new \FrontendForms\InputCheckbox('einzug'); $einzug->setLabel('Hiermit ermächtige ich den Museumsverein Celle e.V. widerruflich, die von mir zu entrichtende Beitragszahlung jährlich bei Fälligkeit zu Lasten meines Kontos mittels Lastschrift einzuziehen. Wenn mein Konto die erforderliche Deckung nicht aufweist, besteht seitens des kontoführenden Geldinstituts keine Verpflichtung zur Einlösung.'); $einzug->setRule('required')->setCustomMessage('Bitte bestätigen Sie die Einzugsermächtigung.'); $form->add($einzug); // Kontoinhaber $kontoinhaber = new \FrontendForms\InputText('kontoinhaber'); $kontoinhaber->setLabel('Kontoinhaber'); $kontoinhaber->setRule('firstAndLastname')->setCustomFieldName('Der Name des Kontoinhabers'); $kontoinhaber->setRule('required')->setCustomMessage('Der Name des Kontoinhabers muss ausgefüllt werden.'); $form->add($kontoinhaber); // Kreditinstitut $kreditinstitut = new \FrontendForms\InputText('kreditinstitut'); $kreditinstitut->setLabel('Kreditinstitut'); $kreditinstitut->setRule('required')->setCustomFieldName('Das Kreditinstitut'); $form->add($kreditinstitut); // BIC $bic = new \FrontendForms\InputText('bic'); $bic->setLabel('BIC'); $bic->setRule('required')->setCustomFieldName('Der BIC-Code'); $form->add($bic); // IBAN $iban = new \FrontendForms\InputText('iban'); $iban->setLabel('IBAN'); $iban->setRule('required')->setCustomFieldName('Der IBAN-Code'); $form->add($iban); // add the privacy field $privacy = new \FrontendForms\Privacy('privacy'); $form->add($privacy); // add the send copy field $sendcopy = new \FrontendForms\SendCopy('sendcopy'); $form->add($sendcopy); $button = new \FrontendForms\Button('submit'); $button->setAttribute('value', 'Absenden'); $form->add($button); if ($form->isValid()) { /** You can use placeholders for the labels and the values of the form fields * This is the modern new way - only available at version 2.1.9 or higher * Big advantage: You do not have to use PHP code and there are a lot of ready-to-use placeholders containing fe the current date, the domain,..... * But it is up to you, if you want to use placeholders or do it the old way * */ $body = '[[TITLE]] [[AUSWAHLVALUE]]<br><br> [[GENDERVALUE]]<br> [[FIRSTNAMELABEL]]: [[FIRSTNAMEVALUE]]<br> [[LASTNAMELABEL]]: [[LASTNAMEVALUE]]<br>'; // check if "Doppelmitgliedschaft" has been selected - otherwise do not add these 2 fields to the mail body if (str_contains($form->getValue('auswahl'), 'Doppelmitgliedschaft')) { $body .= '[[FIRSTNAME2LABEL]]: [[FIRSTNAME2VALUE]]<br> [[LASTNAME2LABEL]]: [[LASTNAME2VALUE]]<br>'; } $body .= '[[ADRESSEVALUE]]<br> [[PLZVALUE]] [[ORTVALUE]]<br> [[EMAILVALUE]]<br> [[PHONELABEL]]: [[PHONEVALUE]]<br> [[GEBLABEL]]: [[GEBVALUE]]<br><br> [[KREDITINSTITUTLABEL]]: [[KREDITINSTITUTVALUE]]<br> [[KONTOINHABERLABEL]]: [[KONTOINHABERVALUE]]<br> [[BICLABEL]]: [[BICVALUE]]<br> [[IBANLABEL]]: [[IBANVALUE]]<br><br>'; // send the form with WireMail $m = wireMail(); if ($form->getValue('sendcopy')) { // send copy to sender $m->to($form->getValue('email')); } $m->to('mail@mail.de')// please change this email address to your own ->from($form->getValue('email')) ->subject('Ein neuer Mitgliedsantrag von ' . $form->getValue('firstname') . ' ' . $form->getValue('lastname')) ->title('<h1>Neuer Mitgliedsantrag</h1>') // this is a new property from this module ->bodyHTML($body) ->sendAttachments($form); if (!$m->send()) { $form->generateEmailSentErrorAlert(); // generates an error message if something went wrong during the sending process } } $content .= $form->render(); echo $content; I have added some additional validation rules to certain fields, some data attributes for the Javascript and some custom labels. Please replace this code with yours (but backup your code first ? ). To show/hide that name fields for the second person, you will need this little JavaScript snippet. <script> let auswahl = document.getElementsByName("contact-auswahl"); if(auswahl.length){ // add event listener to these radio buttons auswahl.forEach(function(elem) { elem.addEventListener("click", function() { let selected = elem.getAttribute('data-value'); let firstname = document.getElementById('firstname-wrapper'); let lastname = document.getElementById('lastname-wrapper'); if(selected == '2'){ firstname.style.display = 'block'; lastname.style.display = 'block'; } else { // hide the fields firstname.style.display = 'none'; lastname.style.display = 'none'; } }); }); } </script> Please add it to your template (fe before the closing body tag). That is all -> the form should work as expected. So please try it out. What I have not done is to make the name fields of the second name required if "Doppelmitgliedschaft" has been selected. It does not work with the "requiredWith" validator. So for this usecase a new validator has to be developed. Maybe I will try to develop this new validator and add it to the next update. Best regards
-
Thank you so much for the detailed answer! I see, there is a lot to learn for me ? I did use and edited your example from github contactform-2.php: <?php declare(strict_types=1); namespace ProcessWire; /* * File description * * Created by Jürgen K. * https://github.com/juergenweb * File name: contactform-2.php * Created: 15.02.2023 */ $form = new \FrontendForms\Form('contact'); $form->setMaxAttempts(0); // disable max attempts //$contacttype = new \FrontendForms\InputCheckboxMultiple('auswahl'); $contacttype = new \FrontendForms\InputRadioMultiple('auswahl'); //$contacttype->setNotes('*'); $contacttype->addOption('Einzelperson (Jahresbeitrag 50,00 EUR)<span class="asterisk">*</span>', 'Einzelperson (Jahresbeitrag 50,00 EUR)'); $contacttype->addOption('Doppelmitgliedschaft (Jahresbeitrag 75,00 EUR)<span class="asterisk">*</span>', 'Doppelmitgliedschaft (Jahresbeitrag 75,00 EUR)'); $contacttype->alignVertical(); $contacttype->setRule('required'); $form->add($contacttype); // add the gender field $gender = new \FrontendForms\Gender('gender'); //$gender->setLabel('Auswählen'); // so Label setzen! $form->add($gender); // add the name field $name = new \FrontendForms\Name('firstname'); $form->add($name); // add the surname field $surname = new \FrontendForms\Surname('lastname'); $form->add($surname); // add the name2 field $name2 = new \FrontendForms\InputText('firstname2'); $name2->setLabel('Vorname (zweite Person)'); $form->add($name2); // add the surname2 field $surname2 = new \FrontendForms\InputText('lastname2'); $surname2->setLabel('Nachname (zweite Person)'); $form->add($surname2); // Adresse $adresse = new \FrontendForms\InputText('adresse'); $adresse->setLabel('Straße und Hausnummer'); $adresse->setRule('required'); $form->add($adresse); // plz $plz = new \FrontendForms\InputText('plz'); $plz->setLabel('Postleitzahl'); $plz->setRule('required'); $form->add($plz); // Ort $ort = new \FrontendForms\InputText('ort'); $ort->setLabel('Ort'); $ort->setRule('required'); $form->add($ort); // add the email field $email = new \FrontendForms\Email('email'); if ($user->isLoggedIn()) { $email->setDefaultValue($user->email); } $form->add($email); // add the phone field $phone = new \FrontendForms\Phone('phone'); $phone->setLabel('Telefon / Mobil'); $phone->setRule('required'); $form->add($phone); // add the Geburtstags field $geb = new \FrontendForms\Phone('geb'); $geb->setLabel('Geburtsdatum'); $form->add($geb); $einzug = new \FrontendForms\InputCheckbox('einzug'); $einzug->setLabel('Hiermit ermächtige ich den Museumsverein Celle e.V. widerruflich, die von mir zu entrichtende Beitragszahlung jährlich bei Fälligkeit zu Lasten meines Kontos mittels Lastschrift einzuziehen. Wenn mein Konto die erforderliche Deckung nicht aufweist, besteht seitens des kontoführenden Geldinstituts keine Verpflichtung zur Einlösung.'); $einzug->setRule('required')->setCustomMessage('Bitte bestätigen Sie die Einzugsermächtigung.');; $form->add($einzug); // Kontoinhaber $kontoinhaber = new \FrontendForms\InputText('kontoinhaber'); $kontoinhaber->setLabel('Kontoinhaber'); $kontoinhaber->setRule('required'); $form->add($kontoinhaber); // Kreditinstitut $kreditinstitut = new \FrontendForms\InputText('kreditinstitut'); $kreditinstitut->setLabel('Kreditinstitut'); $kreditinstitut->setRule('required'); $form->add($kreditinstitut); // BIC $bic = new \FrontendForms\InputText('bic'); $bic->setLabel('BIC'); $bic->setRule('required'); $form->add($bic); // IBAN $iban = new \FrontendForms\InputText('iban'); $iban->setLabel('IBAN'); $iban->setRule('required'); $form->add($iban); // add the privacy field $privacy = new \FrontendForms\Privacy('privacy'); $form->add($privacy); // add the send copy field $sendcopy = new \FrontendForms\SendCopy('sendcopy'); $form->add($sendcopy); $button = new \FrontendForms\Button('submit'); $button->setAttribute('value', 'Absenden'); $form->add($button); if ($form->isValid()) { /** You can grab the values with the getValue() method - this is the default (old) way */ /* $body = $m->title; $body .= '<p>Sender: '.$form->getValue('gender').' '. $form->getValue('firstname').' '.$form->getValue('lastname').'</p>'; $body .= '<p>Mail: '.$form->getValue('email').'</p>'; $body .= '<p>Subject: '.$form->getValue('subject').'</p>'; $body .= '<p>Message: '.$form->getValue('message').'</p>'; */ /** You can use placeholders for the labels and the values of the form fields * This is the modern new way - only available at version 2.1.9 or higher * Big advantage: You do not have to use PHP code and there are a lot of ready-to-use placeholders containing fe the current date, the domain,..... * But it is up to you, if you want to use placeholders or do it the old way * */ $body = '[[TITLE]] [[AUSWAHLVALUE]]<br><br> [[GENDERVALUE]]<br> [[FIRSTNAMELABEL]]: [[FIRSTNAMEVALUE]]<br> [[LASTNAMELABEL]]: [[LASTNAMEVALUE]]<br> [[FIRSTNAME2LABEL]]: [[FIRSTNAME2VALUE]]<br> [[LASTNAME2LABEL]]: [[LASTNAME2VALUE]]<br> [[ADRESSEVALUE]]<br> [[PLZVALUE]] [[ORTVALUE]]<br> [[EMAILVALUE]]<br> [[PHONELABEL]]: [[PHONEVALUE]]<br> [[GEBLABEL]]: [[GEBVALUE]]<br><br> [[KREDITINSTITUTLABEL]]: [[KREDITINSTITUTVALUE]]<br> [[KONTOINHABERLABEL]]: [[KONTOINHABERVALUE]]<br> [[BICLABEL]]: [[BICVALUE]]<br> [[IBANLABEL]]: [[IBANVALUE]]<br><br> // send the form with WireMail $m = wireMail(); if ($form->getValue('sendcopy')) { // send copy to sender $m->to($form->getValue('email')); } $m->to('mail@mail.de')// please change this email address to your own ->from($form->getValue('email')) ->subject('Ein neuer Mitgliedsantrag von ' . $form->getValue('firstname') . ' ' . $form->getValue('lastname')) ->title('<h1>Neuer Mitgliedsantrag</h1>') // this is a new property from this module ->bodyHTML($body) ->sendAttachments($form); if (!$m->send()) { $form->generateEmailSentErrorAlert(); // generates an error message if something went wrong during the sending process } } $content .= $form->render(); echo $content; When selecting the option for "Doppelmitgliedschaft" the fields $name2 ('firstname2') and $surname2 ('lastname2') should appear.
-
Hi @netcarver,I was testing some WireMail integrations and it wasn't possible to install WiremailPostmark: Requires ProcessWire > 3.0.33 PHP 8.1.212.17 >= .selfMIN_PHP Thanks.