<?php /** * Encode our data so that it can be serialised */ namespace App\Traits; use Illuminate\Support\Arr; trait EncodeUTF8 { private array $_encoded = []; // Remember what we've decoded - when calling getAttribute() private function decode(array $values): void { $properties = (new \ReflectionClass($this))->getProperties(); $class = get_class($this); foreach ($properties as $property) { if ($property->isStatic()) continue; $name = $property->getName(); $decode = in_array($name,self::cast_utf8); if ($property->isPrivate()) $name = "\0{$class}\0{$name}"; elseif ($property->isProtected()) $name = "\0*\0{$name}"; if (! array_key_exists($name,$values)) continue; $property->setAccessible(true); try { $property->setValue( $this,$decode ? utf8_decode($values[$name]) : $values[$name] ); } catch (\Exception $e) { dd(['e'=>$e->getMessage(),'name'=>$name,'values'=>$values[$name],'decode'=>$decode]); } } } private function encode(): array { $values = []; $properties = (new \ReflectionClass($this))->getProperties(); $class = get_class($this); foreach ($properties as $property) { // Dont serialize the validation error if (($property->name === 'errors') || $property->isStatic()) continue; $property->setAccessible(true); if (! $property->isInitialized($this)) continue; $name = $property->getName(); $encode = in_array($name,self::cast_utf8); if ($property->isPrivate()) $name = "\0{$class}\0{$name}"; elseif ($property->isProtected()) $name = "\0*\0{$name}"; $property->setAccessible(true); $value = $property->getValue($this); $values[$name] = $encode ? utf8_encode($value) : $value; } return $values; } public function getAttribute($key) { if (in_array($key,self::cast_utf8) && Arr::get($this->attributes,$key) && (! Arr::get($this->_encoded,$key))) { // We need to get it from the parent first, taking into account any casting $this->attributes[$key] = utf8_decode(parent::getAttribute($key)); $this->_encoded[$key] = TRUE; return $this->attributes[$key]; } return parent::getAttribute($key); } public function setAttribute($key,$value) { return parent::setAttribute($key,in_array($key,self::cast_utf8) ? utf8_encode($value) : $value); } }