Compatibility issue with PHPMailer – Akeeba is guilty of writing safe code

Home Forums Quform WordPress Compatibility issue with PHPMailer – Akeeba is guilty of writing safe code

This topic is: resolved
  • This topic has 5 replies, 2 voices, and was last updated 1 week ago by Dirk.
Viewing 6 posts - 1 through 6 (of 6 total)
  • Author
    Posts
  • #37819
    Dirk
    Participant

    Hey 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.
    #37822
    Ally
    Support Staff

    You don't have permission to view this content. Please log in or register and then verify your purchases to gain access.

    #37823
    Ally
    Support Staff

    You don't have permission to view this content. Please log in or register and then verify your purchases to gain access.

    #37826
    Dirk
    Participant

    Hi 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 via wp_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!

    #37827
    Ally
    Support Staff

    You don't have permission to view this content. Please log in or register and then verify your purchases to gain access.

    #37828
    Dirk
    Participant

    HI 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

Viewing 6 posts - 1 through 6 (of 6 total)
  • You must be logged in to reply to this topic.
Be inspired. © 2025 ThemeCatcher Ltd. 20-22 Wenlock Road, London, England, N1 7GU | Company No. 08120384 | Built with React | Privacy Policy