ContactUs Plugin

A reusable Festi Framework plugin that provides a complete "Contact Us" form with validation, spam protection, event-driven extensibility, and asynchronous email notifications.

Features

  • Public contact form page and popup/dialog mode
  • Server-side validation with honeypot spam protection
  • Asynchronous email notifications via the Queues plugin
  • Event hooks for integrating reCaptcha, CRM, or custom logic
  • Configurable intro text and success message via Project Settings
  • HUI component-based form rendering
  • Install scripts for PostgreSQL, MySQL, and MSSQL

Installation

  1. Add the plugin as a git submodule:

    git submodule add [email protected]:FestiPlugins/php_festi_plugin_contactus.git src/site/plugins/ContactUs

  2. Run the appropriate install script for your database:

    psql -U <user> -d <database> -f src/site/plugins/ContactUs/install/install.pgsql.sql

  3. Configure the notification recipients via Festi CLI:

    ./vendor/bin/festi-dgs-exec --plugin Jimbo --dgs festi_settings --action edit --values '{"name":"contact_us_emails","value":"[email protected]"}' --path src/site

Settings

Setting Description
contact_us_emails Comma-separated list of email recipients for notifications
contact_us_intro Introductory text displayed above the form on the contact page
contact_us_success_message Custom message shown after successful submission (defaults to a built-in message)

URL Routes

Pattern Method Area Description
/contact/ onDisplayContactPage default Standalone contact page
/contact/popup/ onJsonFetchPopup default Contact form dialog fragment
/contact/send/ onJsonSubmit default AJAX form submission endpoint

Events

Other plugins can hook into the contact form lifecycle by listening to ContactFormEvent constants:

Event Purpose
EVENT_ON_VALIDATE Add extra validation (e.g. reCaptcha verification)
EVENT_ON_BEFORE_SAVE Mutate form values or cancel the save
EVENT_ON_AFTER_SAVE Post-save actions (e.g. CRM sync)
EVENT_ON_BEFORE_EMAIL Alter email payload or cancel the notification

Example: reCaptcha validation listener

$this->addEventListener(ContactFormEvent::EVENT_ON_VALIDATE, function (ContactFormEvent $event) {
    $result = Core::getInstance()->getPluginInstance('RecaptchaV3')->validate($event->getToken());
    if (!$result['success']) {
        $event->addError($result['message']);
    }
});

Embedding the form

Use the public fetch* methods from any theme template or plugin:

// Embed the form fields on any page
echo $this->plugin->contactUs->fetchForm();

// Render the full contact page (hero + form)
echo $this->plugin->contactUs->fetchPage(['intro' => 'Custom intro text']);

// Render the popup dialog
echo $this->plugin->contactUs->fetchPopup();

Template overrides

Place files with the same name in the project's theme template directory. The framework's template lookup (theme path before plugin path) handles the rest:

  • form.phtml — form fields
  • page.phtml — standalone page layout
  • popup.phtml — dialog wrapper
  • success.phtml — post-submit confirmation

Requirements