CakePHP 4 – Formatting Validation Errors for use with Flash Messages

Written by James McDonald

May 17, 2022

I’ve posted about this before but I think this approach is entirely less complicated

Validation errors in CakePHP come in an array similar to the following:

$errors = [
  'asn_number' => [
    '_empty' => 'ASN cannot be blank',
  ],
  'their_po' => [
    '_empty' => 'Their PO cannot be empty',
  ],
  'spi_number' => [
    '_empty' => 'SPI Number is required',
  ],
  'their_po_date' => [
    '_empty' => 'Their PO Date cannot be empty',
  ],
  'from_address' => [
    '_empty' => 'Missing EDI from Address',
  ],
  'address' => [
    '_empty' => 'Missing EDI destination Address',
  ],
]

But what do you do when you want to nicely display them as the output of $this->Flash->success() or $this->Flash->error() ?

This is what I do to get the errors ready for display. Simply flatten the array and grab the leaves and then format them using CakePHP 4’s Text::toList()

<?php

namespace AppLibUtility;

use \Cake\Utility\Hash;
use \Cake\Utility\Text;

trait ErrorFormatterTrait
{
    /**
     * @param array $validationErrors The Validation Errors from an entity
     * @return string
     */
    public function formatErrors(array $validationErrors = []): string
    {
        // get Validation errors and append them into a string
        $flattened = array_values(Hash::flatten($validationErrors));

        return Text::toList($flattened);
    }
}

<?php
use App\Lib\Utility\ErrorFormatterTrait;

class ItemsController extends Controller
{
    use ErrorFormatterTrait;

    public function edit($id = null)
    {
        $item = $this->Items->get($id, [
            'contain' => [],
        ]);

        if ($this->request->is(['patch', 'post', 'put'])) {
            $item = $this->Items->patchEntity($item, $this->request->getData());
            if ($this->Items->save($item)) {
                $this->Flash->success(__('The item has been saved.'));

                return $this->redirect(['action' => 'index']);
            }
            $errors = $item->getErrors();

            $formattedErrors = $this->formatErrors($errors);

            $this->Flash->error(__('<strong>Errors: </strong> {0}', $formattedErrors));
        }
    }
}

0 Comments

Submit a Comment

Your email address will not be published. Required fields are marked *

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

The reCAPTCHA verification period has expired. Please reload the page.

You May Also Like…