Skip to content

Instantly share code, notes, and snippets.

@TWithers
Created May 13, 2024 16:56
Show Gist options
  • Save TWithers/f8b13dcfe6ccddcdfe67590168a78ab7 to your computer and use it in GitHub Desktop.
Save TWithers/f8b13dcfe6ccddcdfe67590168a78ab7 to your computer and use it in GitHub Desktop.
String Trimming For Livewire
<?php
namespace App\Livewire;
use App\Livewire\Attributes\DontTrim;
use App\Livewire\Attributes\Trim;
trait HandlesStringTrimming
{
public bool $trimsAllStrings = true;
public array $stringTrimInclusions = [];
public array $stringTrimExclusions = [];
public function mountHandlesStringTrimming(): void
{
$reflection = new \ReflectionClass($this);
$properties = $reflection->getProperties();
foreach ($properties as $property) {
$propertyName = $property->getName();
$propertyAttributes = $property->getAttributes(DontTrim::class);
if (count($propertyAttributes) > 0) {
$this->stringTrimExclusions[] = $propertyName;
} else {
$propertyAttributes = $property->getAttributes(Trim::class);
if (count($propertyAttributes) > 0) {
$this->stringTrimInclusions[] = $propertyName;
$this->trimsAllStrings = false;
}
}
}
}
public function updatedHandlesStringTrimming($property): void
{
$propertyPrefix = str($property)->before('.')->toString();
if (
($this->trimsAllStrings && ! in_array($propertyPrefix, $this->stringTrimExclusions)) ||
(! $this->trimsAllStrings && in_array($propertyPrefix, $this->stringTrimInclusions))
) {
if (! $this->isTrimmableType($property)) {
return;
}
$value = $this->getPropertyValue($property);
$this->fill([$property => preg_replace('~^[\s\x{FEFF}\x{200B}]+|[\s\x{FEFF}\x{200B}]+$~u', '', $value) ?? trim($value)]);
}
}
protected function isTrimmableType($property): bool
{
if (str($property)->contains('.')) {
$propertyName = str($property)->afterLast('.');
$objectName = str($property)->beforeLast('.');
$object = data_get($this, $objectName, null);
if (is_object($object)) {
$ref = new \ReflectionProperty($object, (string) $propertyName);
} else {
$ref = null;
}
} else {
$ref = new \ReflectionProperty($this, (string) $property);
}
if (! $ref || ! $ref->getType() || $ref->getType()->getName() !== 'string') {
return false;
}
return true;
}
}
@TWithers
Copy link
Author

This trait will auto-trim on every update everything that can be trimmed.

If you want to limit it, you can leverage property attributes:

  1. #[Trim] and nothing will be trimmed except for those properties with the attribute.
  2. #[DontTrim] and everything will be trimmed except for those properties with the attribute.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment