Skip to content

Forms, spam filtering and marketing tracking

Contact and newsletter forms (Contact Form 7), the custom honeypot that guards them, the domain allow-list that stops legitimate enquiries being marked as spam, and the Force24 marketing tracking that fires behind cookie consent.

Enquiry forms are the site’s lead capture, so a false spam positive costs a real enquiry. The theme therefore layers its own honeypot on top of CF7 and adds an ACF-managed allow-list of trusted email domains that overrides the spam verdict. Force24 is the School’s marketing automation platform and its tracking must not fire before consent.

PathWhat it does
wp-content/themes/supplychainschool/inc/cf7.phpHoneypot form tag, validation, auto-injection, nonce filter
wp-content/themes/supplychainschool/inc/cf7.php:141add_honeypot() — injects three honeypot fields into every form
wp-content/themes/supplychainschool/functions.php:695log_cf7_spam_submission() — the domain allow-list override
wp-content/themes/supplychainschool/inc/components/fc-contact-form.phpContact form block
wp-content/themes/supplychainschool/inc/components/fc-newsletter-sign-up.phpNewsletter block
wp-content/themes/supplychainschool/inc/force24-functions.php:2scss_generate_force24_tracking() on wp_head
wp-content/themes/supplychainschool/assets/js/cookie-notification.jsCookie notice
wp-content/themes/supplychainschool/functions.php:172Enqueues js.cookie.js + cookie-notification.js

inc/cf7.php is a vendored, modified copy of the Contact Form 7 Honeypot plugin, running inside the theme:

  1. wpcf7_add_form_tag(['honeypot'], …) registers a [honeypot name] tag with do-not-store and not-for-mail (:44).
  2. The tag handler (:57) renders a <span> hidden with inline display:none !important; visibility:hidden !important, containing a label and a text input with tabindex="-1" and autocomplete="nope". The inline CSS can optionally be moved to an enqueued stylesheet via the move-inline-css option.
  3. Validation (:117) fails the submission if the field has any value or if the field is absent from $_POST entirely (:132) — so a bot that strips the field is caught as well as one that fills it.
  4. add_honeypot() (:143) filters wpcf7_contact_form_properties and prepends three honeypots to every form that does not already contain the word honeypot: [honeypot your-firstname][honeypot your-mobilephone][honeypot your-companyname].

The field names are chosen to look attractive to autofill-style bots.

CF7’s own nonce verification is disabled: add_filter('wpcf7_verify_nonce', '__return_false') (:153). The honeypot is the replacement anti-bot measure. This also means CF7 submissions work from cached pages, which is likely the real reason.

log_cf7_spam_submission() (functions.php:695) hooks wpcf7_spam:

  1. Only acts when something has already flagged the submission as spam.
  2. error_log('Contact Form 7 marked a form submission as spam.').
  3. Reads the ACF options repeater whitelisted_domains (rows with a domain subfield).
  4. Finds the first value in the posted data that validates as an email.
  5. Compares that email’s domain, lowercased, for an exact match against each allowed domain.
  6. On a match, returns false — not spam.

An earlier attempt at the same thing against Akismet specifically (wpcf7_akismet_intercepted) is commented out immediately above (functions.php:663-693). The live version hooks the generic wpcf7_spam filter instead, which covers Akismet and the honeypot alike.

scss_generate_force24_tracking() (inc/force24-functions.php:2) prints the Force24 loader in wp_head, with a different tracking id and client id per blog: blogs 1, 2, 6 and 7 each have their own pair. Blogs 3 and 5 get nothing.

Only blog 1 is consent-gated. There, the snippet is wrapped in a 1200ms setTimeout that checks window.cookiehub.hasConsented("preferences") before loading (:10-24). Blogs 2, 6 and 7 load the tracker unconditionally.

Cookie consent itself is CookieHub (third-party, injected outside the theme) plus the theme’s own cookie-notification.js built on js.cookie.js.

Google Tag Manager is in header.php, conditionally.

  • Contact Form 7 plugin — required; inc/cf7.php:14 deactivates itself and shows an admin notice if CF7 is missing.
  • ACF options field whitelisted_domains (repeater with a domain subfield) on an options page.
  • Force24 tracking id and client id are hard-coded per blog in inc/force24-functions.php — not options, not constants.
  • Akismet is installed; Flamingo stores submissions.
  • Filters available: wpcf7_honeypot_accessibility_message, wpcf7_honeypot_container_css, wpcf7_honeypot_html_output.
  • CF7 nonce verification is globally off (inc/cf7.php:153). Do not assume a nonce is present on any CF7 submission, and do not re-enable it without checking whether forms still work from cached pages.
  • The allow-list matches the first email-looking value in the submission (functions.php:707). On a form with two email fields (say, “your email” and “colleague’s email”) whichever iterates first wins, and field order in $_POST is not guaranteed to match the form.
  • Domain matching is exact, not suffix-based. Allowing example.com does not allow mail.example.com or example.co.uk.
  • Every honeypot-caught spam submission writes to error_log (functions.php:699) with no rate limiting.
  • Three honeypot fields are prepended to every CF7 form whose markup does not already contain the string “honeypot”. A form that mentions the word for any other reason silently gets none.
  • The honeypot renders a visible-to-screen-readers label (“Please leave this field empty”) inside a display:none container — deliberate, for accessibility, and filterable.
  • Force24 loads unconsented on blogs 2, 6 and 7. Only blog 1 checks CookieHub. If a consent question comes up for the Australian, Carbon or US sites, this is the code to look at.
  • The consent check is a fixed 1200ms setTimeout, not an event listener. If CookieHub loads slower than that, window.cookiehub is undefined and tracking never fires at all — it fails closed, which is the safe direction but means missing data rather than an error.
  • Blog 6 (Carbon Calculator) has its own Force24 pair, so calculator page views are tracked as marketing activity.
  • New trusted domain: add a row to the whitelisted_domains ACF options repeater. No code change.
  • New Force24 site: add an elseif ($blog_id == N) branch in inc/force24-functions.php with that site’s ids, and copy the CookieHub consent wrapper from the blog 1 branch — the other branches are the pattern you do not want to follow.
  • Changing the honeypot field names means changing them in add_honeypot() only; the validation is generic over the tag name.
  • If you replace the honeypot with anything else, re-check wpcf7_verify_nonce — the theme currently relies on the honeypot as the only bot barrier.
  • Verify by hand: submit a form normally; submit with a honeypot field filled (expect the spam message); submit from an allow-listed domain with Akismet in test mode and confirm it lands in Flamingo as not-spam; check error_log for the spam line.
  • Deliberately not abstracted: inc/cf7.php is a vendored plugin copy. Keep the upstream structure recognisable so it can be diffed against the original.

None.

Related: [[acf-flexible-content-blocks]], [[site-chrome-and-navigation]], [[member-directory-and-stats]].