Fields & Validation
Flows

Presentation

Business

Persitance

Business

Persitance

Presentation

Views & Controllers

Presentation

Business

Persitance

Views & Controllers

Models

Presentation

Business

Persitance

Views & Controllers

Models

Repositories

Presentation

Business

Persitance

Views & Controllers

Models

Repositories

Dependency

Flow

Presentation

Business

Persitance

Views & Controllers

Models

Repositories

✨🔥Holy barriers of trust 🔥✨

✨🔥Holy barriers of trust 🔥✨

View

Responsibility:

Make a user experience so amazing the donor wants to cry with joy.

Depends On:

The Controller to process the form request.

View

Responsibility:

Make a user experience so amazing the donor wants to cry with joy.

Depends On:

The Controller to process the form request.

{
    "name": "Trusty Tim",
    "email": "tim@legitemail.com",
    "amount": "; DELETE wp_posts;",
    "agree": "1"
}

Controller

Responsibility:

Recieve requests

Validate

Do business-y things

Respond

Depends On:

The models to do business-y things about business.

{
    "name": "Trusty Tim",
    "email": "tim@legitemail.com",
    "amount": "; DELETE wp_posts;",
    "agree": "1"
}
<?php

class DonationFormController {
    public function __invoke() {
    	$name = $_POST['name'];
    	$email = $_POST['email'];
        $amount = $_POST['amount'];
        $agree = $_POST['agree'];
        
        $donation = new Donation(
            $name,
            $email,
            $amount
        );
        
        $donation->save();
    }
}

Controller

Responsibility:

Recieve requests

Validate

Do business-y things

Respond

Depends On:

The models to do business-y things about business.

{
    "name": "Trusty Tim",
    "email": "tim@legitemail.com",
    "amount": "; DELETE wp_posts;",
    "agree": "1"
}
<?php

class DonationFormController {
    public function __invoke() {
    	$name = $_POST['name'];
    	$email = $_POST['email'];
        $amount = $_POST['amount'];
        $agree = $_POST['agree'];
        
        $donation = new Donation(
            $name,
            $email,
            $amount
        );
        
        $donation->save();
    }
}

Controller

Responsibility:

Recieve requests

Validate

Do business-y things

Respond

"name": "Trusty Tim",
"email": "tim@legitemail.com",
"amount": "; DELETE wp_posts;",
"agree": "1"
<?php

class DonationFormController {
    public function __invoke() {
        // Retrieve the data from the request
        $name = $_POST['name'];
        $email = $_POST['email'];
        $amount = $_POST['amount'];
        $agree = $_POST['agree'];
        
        // Validation — the hero we need
        
        // Innocently do business things
        $donation = new Donation(
            $name,
            $email,
            $amount
        );
        
        $donation->save();
    }
}

Controller

Responsibility:

Recieve requests

Validate

Do business-y things

Respond

<?php

class DonationFormController {
    public function __invoke() {        
        $validator = new Validator($_POST, [
            'name' => ['required', 'max:255'],
            'email' => ['required', 'email'],
            'amount' => ['required', 'integer'],
            'agree' => ['required', 'boolean']
        ])
        
        if ($validator->passes()) {
            $values = $validator->validated();
        } else {
        	wp_send_json_error($validator->errors());
        }
        
        // Safe, trustworth data ❤️
        $donation = new Donation(
            $values['name'],
            $values['email'],
            $values['amount']
        );
        
        $donation->save();
        
        // respond
        wp_send_json_success();
    }
}
"name": "Trusty Tim",
"email": "tim@legitemail.com",
"amount": "; DELETE wp_posts;",
"agree": "1"

Validation Library

<?php

class DonationFormController {
    public function __invoke() {        
        $validator = new Validator($_POST, [
            'name' => ['required', 'max:255'],
            'email' => ['required', 'email'],
            'amount' => ['required', 'integer'],
            'agree' => ['required', 'boolean']
        ])
        
        if ($validator->passes()) {
            $values = $validator->validated();
        } else {
        	wp_send_json_error($validator->errors());
        }
        
        // Safe, trustworth data ❤️
        $donation = new Donation(
            $values['name'],
            $values['email'],
            $values['amount']
        );
        
        $donation->save();
        
        // respond
        wp_send_json_success();
    }
}

Fields API

<?php

/**
 * Field API:
 *
 * A mid-level API for building forms.
 *
 * 4 Primitive Types:
 * - Node
 *   - Field: node that takes user input -- Text, Email, Select, Radio, Checkbox, etc.
 *   - Element: node that does not take user input -- Paragraph, Heading, etc.
 *   - Group: node that contains other nodes
 */

$form = new Form( 'profile' );

$form->append(
    Section::make('personal')
        ->append(
            Text::make('firstName')
                ->label('First Name')
                ->rules('required', 'max:255'),

            Text::make('lastName')
                ->label('Last Name')
                ->rules('required', 'max:255'),
            
            give_field('text', 'company')
                ->label('First Name')
                ->rules('required', 'max:255'),

            Email::make('email')
                ->label('Email')
                ->rules('required', 'email')
        )
);

$form->insertAfter('lastName', Text::make('middleName')->label('Middle Name'));

TBD?

In Conclusion

  • Validate in your controller before sending data to the business models
  • Keep the responsibility between layers distinct
  • Use controllers to receive requests and send responses
  • Use frameworks like Validation and Joi so you're not re-inventing the validation wheel
  • If the Field API looks like something that would be useful for broader use, let me know!

Fields & Validations - StellarWP Tech Talk

By Jason Adams

Fields & Validations - StellarWP Tech Talk

  • 190