Home › Forums › Quform WordPress › Compatibility issue with PHPMailer – Akeeba is guilty of writing safe code
- This topic has 5 replies, 2 voices, and was last updated 1 week ago by
Dirk.
- AuthorPosts
- June 12, 2025 at 2:42 pm #37819
Dirk
ParticipantHey folks,
just wanted to share a lovely little debugging journey I went through involving Quform and Akeeba Backup – specifically, an issue where Quform forms silently broke due to PHPMailer conflicts.
Naturally, I assumed it was a classic plugin collision, so I contacted Nicholas from Akeeba (you know, that guy who built one of the most widely respected backup systems in the CMS universe).
Turns out – surprise! – Akeeba is doing everything by the book. It uses PHPMailer via Composer only if the class hasn’n’t already been loaded. Just like PHP has recommended for, oh I don’t know, two decades now. Something like:
if (!class_exists(PHPMailer\PHPMailer\PHPMailer::class, false)) {
require_once ABSPATH . WPINC . '/class-phpmailer.php';
}
Seems fair, right?
Except someone (no names, of course
) is doing a direct require_once on the legacy class-phpmailer.php file without checking if the class is already defined – causing exactly the kind of conflict that makes debugging so… spiritually enriching.
Oh, and just to add some icing to the cake:
Instead of reaching out, Quform apparently decided to publicly blame Akeeba:
Classy move.
Nicholas’ response?
Let’s just say it was equal parts educational, clinical, and… absolutely savage.He even offered to add a workaround for Quform’s reckless loading behavior — if only someone had asked. Instead, they got themselves publicly called out in a way that may end up being immortalized in source code comments.
Ooooof.
And while I’m here venting:
Can we also talk about how incredibly annoying it is that I’ve had to verify my purchase multiple times just to access your forum? Once is fair. But over and over again? That’s just user-hostile. Especially when you’re trying to troubleshoot a bug that isn’t even your fault.
Anyway, dear ThemeCatcher devs:
If you’re reading this, maybe a humble class_exists() check next time?
You know — for peace, harmony, working contact forms, and happy customers who don’t have to keep digging out Envato receipts like it’s a scavenger hunt.
Best regards,
Dirk(Certified Bug Magnet & Occasional Code Therapist)
Attachments:
You must be logged in to view attached files.June 14, 2025 at 9:53 am #37822Ally
Support StaffYou don't have permission to view this content. Please log in or register and then verify your purchases to gain access.
June 14, 2025 at 10:42 am #37823Ally
Support StaffYou don't have permission to view this content. Please log in or register and then verify your purchases to gain access.
June 16, 2025 at 1:26 pm #37826Dirk
ParticipantHi Ally,
Thanks again for the update and for taking the time to debug this.
I just wanted to clarify one important detail regarding the test you ran:
The fatal error you encountered —
Cannot declare class PHPMailer\PHPMailer\PHPMailer, because the name is already in use
— happens **because the Composer autoloader (triggered by instantiating PHPMailer)** loads the class *before* WordPress tries to load its legacy shim viawp_mail()
. So when WordPress then includes/wp-includes/PHPMailer/PHPMailer.php
, it attempts to re-declare the class, which PHP rightfully blocks.This is not caused by Akeeba doing something wrong — it’s actually behaving exactly as expected for a Composer-loaded class.
###
The root of the issue:
To avoid this conflict, the following pattern should be used:if (!class_exists('\\PHPMailer\\PHPMailer\\PHPMailer', false)) { require_once ABSPATH . WPINC . '/PHPMailer/PHPMailer.php'; require_once ABSPATH . WPINC . '/PHPMailer/Exception.php'; }
Also important:
This issue is not limited to Akeeba Backup Pro. It also happens with the free version of Akeeba Backup, which is publicly available on the akeeba Website. So anyone running the free version will also experience the same AJAX error when using QuForm.Just having Akeeba Backup active — no matter the edition — is enough to trigger the problem due to the way PHPMailer gets loaded. So it’s definitely reproducible without needing a commercial license!
So please grab yourself a copy of Akeeba Free Version and test it!
Thank you in advance!
June 16, 2025 at 3:28 pm #37827Ally
Support StaffYou don't have permission to view this content. Please log in or register and then verify your purchases to gain access.
June 16, 2025 at 9:15 pm #37828Dirk
ParticipantHI Ally!
Thanks again for the quick reply — I really appreciate your openness to fixing it in QuForm, even if it feels like a strange workaround from your point of view.
FYI: I had never ever any problems with akeeba!
Just to clarify though: the use of
class_exists(..., false)
is actually a recommended practice in environments where multiple autoloaders (like Composer’s) may be present. It’s not about avoiding autoloading per se — it’s about preventing *double class declarations* when mixing legacy file includes and modern autoloading. This is especially relevant now that many plugins follow PSR-4 standards and load dependencies via Composer.I do agree with your point that prefixing (via tools like Strauss) can help reduce conflicts even further — especially for shared libraries like PHPMailer. But in this case, the problem stems from WordPress loading a legacy shim for PHPMailer even though Composer already loaded the namespace version.
Thanks again for working towards a clean solution. I think everyone wins here — and many users will be spared from mysterious AJAX errors because of this small change.
Best regads, Dirk
- AuthorPosts
- You must be logged in to reply to this topic.