Saving contact form submissions to DB

SS4

Does anyone know any good solutions for saving contact form submissions to the database and an admin panel in the CMS?

I did use uncheese’s permamail, but not compatible with SS4 which is a shame because it worked really well.

Thanks in advance.

Regards

I don’t know of a module but I usually just define a DataObject (e.g. ContactFormSubmission) with the same fields as the contact form, and set up a ModelAdmin interface to view them. Then you can load the form data in to a new object and save it at the same time you send an email for it.

I just happened to be working on exactly this when I saw your post. This is my method…

I’m using UndefinedOffset’s SortableGridfield module as well, so either add that to your composer.json file or use SS’s gridfield and modify the code below.

Contact.php

        <?php
    use SilverStripe\CMS\Model\SiteTree;
    use SilverStripe\Forms\TextareaField;
    class ContactPage extends Page {
        private static $db = [
            'Success'        => 'Varchar(255)'
        ];
        public function getCMSFields() {
            $fields = parent::getCMSFields();
            // Hero
            $fields->addFieldToTab('Root.Main', TextareaField::create('Success', 'Success message after someone submits the form.'), 'Content');
            return $fields;
        }
    }

ContactPageController.php

    <?php
    use SilverStripe\CMS\Controllers\ContentController;
    use SilverStripe\Forms\Form;
    use SilverStripe\Forms\FieldList;
    use SilverStripe\Forms\TextField;
    use SilverStripe\Forms\EmailField;
    use SilverStripe\Forms\TextareaField;
    use SilverStripe\Forms\FormAction;
    use SilverStripe\Forms\RequiredFields;
    use SilverStripe\Control\Email\Email;
    use SilverStripe\SiteConfig\SiteConfig;
    class ContactPageController extends PageController {
        private static $allowed_actions = array(
            'ConnectForm'
        );
        public function ConnectForm() {
            $fields = new FieldList(
                TextField::create('Name', 'Name')->setAttribute('placeholder', '*Name (Required)'),
                EmailField::create('Email', 'Email')->setAttribute('placeholder', '*Email (Required)'),
                TextField::create('Phone', 'Phone')->setAttribute('placeholder', 'Phone'),
                TextareaField::create('Message', 'Message')->setAttribute('placeholder', 'Comments')
            );
            $actions = new FieldList(
                FormAction::create("doSubmitForm", 'Submit')
            );
            $required = new RequiredFields('Name','Email');
            $form = new Form($this, 'ConnectForm', $fields, $actions, $required);
            $form->setFormMethod('POST', true);
            return $form;
        }

        public function doSubmitForm($data, $form) {
            // Send an email notification to myself
            $sendTo = 'myemail@example.com';
            $email = new Email();
            $email->setTo($sendTo);
            $email->setFrom($data['Email']);
            $email->setSubject('Website Contact Submission');
            $message = "
                <p><strong>Name:</strong> {$data['Name']}</p>
                <p><strong>Email:</strong> {$data['Email']}</p>
                <p><strong>Phone:</strong> {$data['Phone']}</p>
                <p><strong>Message:</strong> {$data['Message']}</p>
            ";
            $email->setBody($message);
            $email->send();

            // Create a record in the DB
            $submission = Contact::create();
            $form->saveInto($submission);
            $submission->write();

            //Grab success message from $this page and redirect back
            $thx = $this->Success;
            $form->sessionMessage($thx, 'success');
            return $this->redirectBack();
        }
    }

My Contact.php object

    <?php
    use SilverStripe\CMS\Model\SiteTree;
    use SilverStripe\ORM\DataObject;
    class Contact extends DataObject {
        private static $create_table_options = [
            'MySQLDatabase' => 'ENGINE=MyISAM'
        ];
        private static $db = [
            'Name'              => 'Varchar(255)',
            'Email'             => 'Varchar(255)',
            'Phone'             => 'Varchar(15)',
            'Message'           => 'Text',
            'SortOrder'         => 'Int'
        ];
        private static $summary_fields = [
            'Name',
            'Email'
        ];
        private static $default_sort = 'SortOrder';
    }

Manage the objects with model admin using UndefinedOffset’s SortableGridfield.
ContactAdmin.php

    <?php
    use SilverStripe\Admin\ModelAdmin;
    class ContactAdmin extends ModelAdmin {
        private static $managed_models = [
            'Contact'
        ];
        private static $url_segment = 'contacts';
        private static $menu_title = 'Contacts';
        public function getEditForm($id = null, $fields = null) {
            $form=parent::getEditForm($id, $fields);
            if($this->modelClass=='Contact' && $gridField=$form->Fields()->dataFieldByName($this->sanitiseClassName($this->modelClass))) {
                if($gridField instanceof GridField) {
                    $gridField->getConfig()->addComponent(new GridFieldSortableRows('SortOrder'));
                }
            }
            return $form;
        }
    }
1 Like

Thanks man, works a treat! much appreciated.

Now that your form submissions are being saved to the database, how do you plan to extract that data back out?

I am just now considering using a SS form for monthly data collection on our staff portal, which is already content-managed by SS. Using web forms to write to the database is ideal for my needs, but I also need to connect to the MySQL database independently of SS to query against the database for statistical reporting purposes. Can any of you tell me how to structure a connection string to the MySQL database?

I found some links in older posts which purported to get me closer to an answer, but all those links were broken. Incidentally, we are a SS 3.x site.