Trimming whitespace from Drupal form submissions using an HTTP middleware
Leading and trailing whitespaces. The bane of normalized data everywhere. It seems like a constant task that needs to be performed on incoming user data. When working with Laravel, I use the TrimStrings
middleware. Calls PHP's built-in trim
function on all string values for the request query and input values – including JSON! While working on my project WhiskeyDex, I noticed how mobile device keyboards always add trailing whitespace when using the autocomplete functionality. This, in turn, meant user-created data will end up with trailing whitespaces. I started to just quick-fix in the single instance and realized it should be solved once and for all.
Drupal does not provide as many developer-friendly tools as Laravel, so I needed to recreate my version of the TrimStrings
middleware. It's fairly simple, requiring one class and its service registration. Note: the following code is for PHP 8.1.
In your module, create a src/StackMiddleware/TrimMiddleware.php
file with the following:
<?php
declare(strict_types=1);
namespace Drupal\whiskeydex\StackMiddleware;
use Symfony\Component\HttpFoundation\InputBag;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\HttpKernelInterface;
final class TrimMiddleware implements HttpKernelInterface {
public function __construct(
private readonly HttpKernelInterface $app
) {
}
public function handle(
Request $request,
int $type = self::MAIN_REQUEST,
bool $catch = TRUE): Response {
$this->trimBag($request->query);
$this->trimBag($request->request);
return $this->app->handle($request);
}
private function trimBag(InputBag $bag): void {
$bag->replace($this->trimArray($bag->all()));
}
private function trimArray(array $array): array {
return array_map(
function ($value) {
if (is_array($value)) {
return $this->trimArray($value);
}
return is_string($value) ? trim($value) : $value;
},
$array
);
}
}
The real work is in trimArray
, which iterates through the array, and any nested ones, returning trimmed strings.
Then register the service in your module’s services.yml
:
services:
http_middleware.trim:
class: Drupal\whiskeydex\StackMiddleware\TrimMiddleware
arguments: ['@kernel']
tags:
- { name: http_middleware }
Here is a link to a gist of the code as well: https://gist.github.com/mglaman/4533051f0ec50ebd698bbde93c1ac79b