for testing and deploying your application
for finding and fixing issues
for empowering human code reviews
<?php
namespace Spatie\BladeX;
use Closure;
use Illuminate\Contracts\Support\Arrayable;
use Illuminate\Support\Str;
use ReflectionClass;
use ReflectionMethod;
use ReflectionProperty;
abstract class ViewModel implements Arrayable
{
protected $ignore = [];
public function toArray(): array
$class = new ReflectionClass($this);
$publicProperties = collect($class->getProperties(ReflectionProperty::IS_PUBLIC))
->reject(function (ReflectionProperty $property) {
return $this->shouldIgnore($property->getName());
})
->mapWithKeys(function (ReflectionProperty $property) {
return [$property->getName() => $this->{$property->getName()}];
});
$publicMethods = collect($class->getMethods(ReflectionMethod::IS_PUBLIC))
->reject(function (ReflectionMethod $method) {
return $this->shouldIgnore($method->getName());
->mapWithKeys(function (ReflectionMethod $method) {
return [$method->getName() => $this->createVariableFromMethod($method)];
return $publicProperties->merge($publicMethods)->all();
}
protected function shouldIgnore(string $methodName): bool
if (Str::startsWith($methodName, '__')) {
return true;
return in_array($methodName, $this->ignoredMethods());
protected function ignoredMethods(): array
return array_merge([
'toArray',
'toResponse',
'view',
], $this->ignore);
protected function createVariableFromMethod(ReflectionMethod $method)
if ($method->getNumberOfParameters() === 0) {
return $this->{$method->getName()}();
return Closure::fromCallable([$this, $method->getName()]);