Skip to content

Latest commit

 

History

History
315 lines (268 loc) · 12.4 KB

README.md

File metadata and controls

315 lines (268 loc) · 12.4 KB

EasyForm

EasyForm is a MODX extra which provides basic form handling functionalities using Illuminate Validation to handle the form validation which provides lots of default validation rules and you can easily provide custom error messages or create your own custom validator rules.

The Fenom parser provided by pdoTools is required in order to work with EasyForm.

More information about validation and all the, by default, built in validation rules please read the validation section from Laravel.

Requirements

  • pdoTools: pdoTools is required due to the Fenom parser it provides.

Key features

  1. File driven: Designed to work using PHP classes and file based chunks.
  2. Utilizes Illuminate validation which includes lots of default validation rules.
  3. Comes with useful default plugins

TODO

  1. Add Recaptcha plugin
  2. Add default login/registration plugins

Default plugins

The following plugins are included by default.

Plugin Description
Email Use this plugin to send an email once the form has been submitted.
AutoResponder Use this plugin to send an email once the form has been submitted. Works exactly the same as the Email plugin which it's extends.
Redirect Redirect the user after form submission by providing a resource id or URL.

Add your own plugins

Create a plugin class that extends the BasePlugin class and make sure it's loaded by the snippet by adding the path to the scriptproperties.

{set $form = '!EasyForm' | snippet : [
    'pluginPaths' => [
        '{base_path}/customplugins/',
        '{core_path}/customplugins/',
        '{assets_path}/customplugins/'
    ],
    'plugins' => [
        'Redirect' => [
            'to' => 2
        ],
        'SomePlugin' => []
    ],
    'submitVar'     => 'submitvar',
    'rules'         => [
        'name'  => ['required'],
        'email' => ['required', 'email']
    ]
]}
<?php

use Sterc\EasyForm\Plugins\BasePlugin;

class SomePlugin extends BasePlugin
{
    public function onInitForm($form, $properties)
    {
        $form->request->set('name', 'some value');

        return true;
    }
}

Plugin events

The following plugin events are available.

Event Description
onInitForm Trigged while initialising the form, before rendering it. Can be used for pre-form validation or for setting form values before the form is loaded.
onFormSubmitted Triggered once form is submitted and validation has been passed.

Add your own validation rules

Adding your own custom validation rules can be done by creating a new class which implements the Rule class:

<?php
namespace App\Rules;
 
use Illuminate\Contracts\Validation\Rule;
 
class Uppercase implements Rule
{
      /**
     * Determine if the validation rule passes.
     *
     * @param  string  $attribute
     * @param  mixed  $value
     * @return bool
     */
    public function passes($attribute, $value)
    {
        return strtoupper($value) === $value;
    }
 
    /**
     * Get the validation error message.
     *
     * @return string
     */
    public function message()
    {
        return 'The :attribute must be uppercase.';
    }
}

Then add the path where your rule class lives into the rulePaths array and the rule to the field you'd like to validate by defining the fully classified class name as a string, like so: 'new App\Rules\Uppercase'.

{set $form = '!EasyForm' | snippet : [
    'rulePaths' => [
        '{base_path}/customrules/',
    ',
    'rules' => [
        'name'  => ['required', 'new App\Rules\Uppercase'],
    ]
],

Example usage

Please view this extensive example for all possible properties and usage:

{set $form = '!EasyForm' | snippet : [
    'pluginPaths' => [
        '{base_path}/customplugins/'
    ],
    'rulePaths' => [
        '{base_path}/customrules/'
    ],
    'plugins' => [
        'Email' => [
            'tpl'             => '@FILE email.tpl',
            'to'              => ['email' => '[email protected]', 'name' => 'John Doe To'],
            'from'            => ['email' => '[email protected]', 'name' => 'John Doe'],
            'reply-to'        => ['email' => '[email protected]', 'name' => 'John Doe Reply'],
            'cc'              => [
                ['email' => '[email protected]', 'name' => 'John Doe CC'],
                ['email' => '[email protected]', 'name' => 'John Doe CC2'],
                ['email' => '[email protected]']
            ],
            'bcc'             => ['email' => '[email protected]', 'name' => 'John Doe BCC'], 
            'html'            => true,
            'convertNewlines' => true,
            'subject'         => 'My subject - [[+name]] {$name}',
            // 'subjectField'   => 'topic', Can be used instead of subject in order to make a dynamic subject based on specified form field value.
            'multiWrapper'    => 'Before {$values} After',
            'multiSeparator'  => ', ',
            'selectEmailToAddresses' => [
                ['email' => '[email protected]', 'name' => 'John Doe Receiver 1'],
                ['email' => '[email protected]', 'name' => 'John Doe Receiver 2'],
            ]
            'selectEmailToField'     => 'receiver',
            'attachments' => [
                '{base_path}/uploads/fallback.png',
                '{base_path}/uploads/background.jpg'
            ],
            'attachFilesToEmail' => true
        ],
        'AutoResponder' => [
            'tpl'                 => '@FILE email.tpl',
            'to'                  => ['email' => '[email protected]', 'name' => 'John Doe To'],
            'from'                => ['email' => '[email protected]', 'name' => 'John Doe'],
            'subject'             => 'Autoresponder - [[+name]] {$name}',
            'attachFilesToEmail'  => true
        ],
        'Redirect' => [
            'to'     => 'https://www.google.com?',
            'scheme' => 'full',
            'params' => [
                'test'    => 1,
                'success' => 'value'
            ]
        ]
    ],
    'submitVar'     => 'submitvar',
    'rules'         => [
        'name'  => ['required', 'new App\Rules\Uppercase'],
        'name2'  =>['required', 'same:name'],
        'topic' => ['required'],
        'email' => ['required', 'email']
    ],
    'messages' => [
        'required'      => 'This is a mandatory message field that overrides the default message.',
        'name.required' => '":attribute" is a required field with a custom error message.'
    ]
]}

    <form action="{$_modx->resource.id | url}" method="post" enctype="multipart/form-data" novalidate>
        <input type="hidden" name="submitvar" value="submitted"/>

        <div class="input-group mb-3">
            <input type="text" class="form-control {$form->getError('name') ? 'is-invalid' : ''}" name="name" placeholder="Name" value="{$form->getValue('name')}"/>
            
            {if $form->getError('name')}
                <div class="invalid-feedback">{$form->getError('name')}</div>
            {/if}
        </div>

            <div class="input-group mb-3">
            <input type="text" class="form-control {$form->getError('name2') ? 'is-invalid' : ''}" name="name2" placeholder="Name2" value="{$form->getValue('name2')}"/>
            
            {if $form->getError('name2')}
                <div class="invalid-feedback">{$form->getError('name2')}</div>
            {/if}
        </div>

        <div class="input-group mb-3">
            <select class="form-control {$form->getError('topic') ? 'is-invalid' : ''}"  name="topic" placeholder="Topic">
                <option value=""></option>
                <option value="General" {$form->getValue('topic') === 'General' ? 'selected' : ''}>General</option>
                <option value="Sales" {$form->getValue('topic') === 'Sales' ? 'selected' : ''}>Sales</option>
            </select>
            
            {if $form->getError('topic')}
                <div class="invalid-feedback">{$form->getError('topic')}</div>
            {/if}
        </div>

        <div class="input-group mb-3">
            <select class="form-control {$form->getError('receiver') ? 'is-invalid' : ''}"  name="receiver" placeholder="Receiver">
                <option value=""></option>
                <option value="1" {$form->getValue('receiver') === '[email protected]' ? 'selected' : ''}>[email protected]</option>
                <option value="2" {$form->getValue('receiver') === '[email protected]' ? 'selected' : ''}>[email protected]</option>
            </select>
            
            {if $form->getError('receiver')}
                <div class="invalid-feedback">{$form->getError('receiver')}</div>
            {/if}
        </div>

        <div class="input-group mb-3">
            <select class="form-control {$form->getError('brands') ? 'is-invalid' : ''}"  name="brands[]" placeholder="Brands" multiple>
                <option value=""></option>
                <option value="Audi" {$form->isSelected('brands', 'Audi') ? 'selected' : ''}>Audi</option>
                <option value="BMW" {$form->isSelected('brands', 'BMW') ? 'selected' : ''}>BMW</option>
            </select>
            
            {if $form->getError('topic')}
                <div class="invalid-feedback">{$form->getError('topic')}</div>
            {/if}
        </div>

        <div class="input-group mb-3">
                <div class="form-check">
                <input class="form-check-input" name="interests[]" type="checkbox" value="Cars" id="cars" {$form->isSelected('interests', 'Cars') ? 'checked' : ''}>
                <label class="form-check-label" for="cars">
                Cars
                </label>
            </div>
            <div class="form-check">
                <input class="form-check-input" name="interests[]" type="checkbox" value="Games" id="games" {$form->isSelected('interests', 'Games') ? 'checked' : ''}>
                <label class="form-check-label" for="games">
                Games
                </label>
            </div>
        </div>

        <input type="file" id="testfile" name="filename">

        <div class="input-group mb-3">
            <input type="email" class="form-control {$form->getError('email') ? 'is-invalid' : ''}" name="email" placeholder="Email" value="{$form->getValue('email')}"/>
            
            {if $form->getError('email')}
                <div class="invalid-feedback">{$form->getError('email')}</div>
            {/if}
        </div>

        <button type="submit" class="btn btn-primary">Submit</button>
    </form>

    {if $form->isSubmitted() && $form->hasErrors()}
        <p>Form has errors.</p>
    {/if}

Development

Lang file conversion

Script to convert laravel-lang validation messages to MODX lexicon file

$array contains the laravel-lang validation messages array from https://github.com/overtrue/laravel-lang.

$output = [];
foreach ($array as $key => $value) {
    if (!is_array($value)) {
        $output[] = '$_lang[\'' . $key . '\'] = \'' . addslashes($value) . '\';';
    } else {
        foreach ($value as $childKey => $childValue) {
            $output[] = '$_lang[\'' . $key . ':' . $childKey . '\'] = \'' . addslashes($childValue) . '\';';
        }
    }
}

var_dump(implode('<br/>', $output));
exit;