Skip to content

Commit

Permalink
Other small ComponentFactory optimizations
Browse files Browse the repository at this point in the history
  • Loading branch information
smnandre committed Nov 11, 2024
1 parent d4092c2 commit 0acc77c
Showing 1 changed file with 24 additions and 30 deletions.
54 changes: 24 additions & 30 deletions src/TwigComponent/src/ComponentFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,20 +25,19 @@
*/
final class ComponentFactory implements ResetInterface
{
private static array $mountMethods = [];
private array $mountMethods = [];

/**
* @param array<string, array> $config
* @param array<class-string, string> $classMap
* @param array<class-string, array<string, string[]> $classMounts
*/
public function __construct(
private ComponentTemplateFinderInterface $componentTemplateFinder,
private ServiceLocator $components,
private PropertyAccessorInterface $propertyAccessor,
private EventDispatcherInterface $eventDispatcher,
private array $config,
private array $classMap,
private readonly array $classMap,
) {
}

Expand Down Expand Up @@ -88,22 +87,23 @@ public function create(string $name, array $data = []): MountedComponent
public function mountFromObject(object $component, array $data, ComponentMetadata $componentMetadata): MountedComponent
{
$originalData = $data;
$data = $this->preMount($component, $data, $componentMetadata);
$event = $this->preMount($component, $data, $componentMetadata);
$data = $event->getData();

$this->mount($component, $data, $componentMetadata);

// set data that wasn't set in mount on the component directly
foreach ($data as $property => $value) {
if ($this->propertyAccessor->isWritable($component, $property)) {
$this->propertyAccessor->setValue($component, $property, $value);

unset($data[$property]);
if (!$componentMetadata->isAnonymous()) {
// set data that wasn't set in mount on the component directly
foreach ($data as $property => $value) {
if ($this->propertyAccessor->isWritable($component, $property)) {
$this->propertyAccessor->setValue($component, $property, $value);
unset($data[$property]);
}
}
}

$postMount = $this->postMount($component, $data, $componentMetadata);
$data = $postMount['data'];
$extraMetadata = $postMount['extraMetadata'];
$data = $postMount->getData();

// create attributes from "attributes" key if exists
$attributesVar = $componentMetadata->getAttributesVar();
Expand All @@ -120,9 +120,9 @@ public function mountFromObject(object $component, array $data, ComponentMetadat
return new MountedComponent(
$componentMetadata->getName(),
$component,
new ComponentAttributes(array_merge($attributes, $data)),
new ComponentAttributes([...$attributes, ...$data]),
$originalData,
$extraMetadata,
$postMount->getExtraMetadata(),
);
}

Expand Down Expand Up @@ -154,7 +154,7 @@ private function mount(object $component, array &$data, ComponentMetadata $compo
return;
}

$mount = self::$mountMethods[$component::class] ??= (new \ReflectionClass($component))->getMethod('mount');
$mount = $this->mountMethods[$component::class] ??= (new \ReflectionClass($component))->getMethod('mount');

$parameters = [];
foreach ($mount->getParameters() as $refParameter) {
Expand All @@ -172,40 +172,34 @@ private function mount(object $component, array &$data, ComponentMetadata $compo
$mount->invoke($component, ...$parameters);
}

private function preMount(object $component, array $data, ComponentMetadata $componentMetadata): array
private function preMount(object $component, array $data, ComponentMetadata $componentMetadata): PreMountEvent
{
$event = new PreMountEvent($component, $data, $componentMetadata);
$this->eventDispatcher->dispatch($event);
$data = $event->getData();

$data = $event->getData();
foreach ($componentMetadata->getPreMounts() as $preMount) {
if (null !== $newData = $component->$preMount($data)) {
$data = $newData;
$event->setData($data = $newData);
}
}

return $data;
return $event;
}

/**
* @return array{data: array<string, mixed>, extraMetadata: array<string, mixed>}
*/
private function postMount(object $component, array $data, ComponentMetadata $componentMetadata): array
private function postMount(object $component, array $data, ComponentMetadata $componentMetadata): PostMountEvent
{
$event = new PostMountEvent($component, $data, $componentMetadata);
$this->eventDispatcher->dispatch($event);
$data = $event->getData();

$data = $event->getData();
foreach ($componentMetadata->getPostMounts() as $postMount) {
if (null !== $newData = $component->$postMount($data)) {
$data = $newData;
$event->setData($data = $newData);
}
}

return [
'data' => $data,
'extraMetadata' => $event->getExtraMetadata(),
];
return $event;
}

/**
Expand Down Expand Up @@ -244,6 +238,6 @@ private function throwUnknownComponentException(string $name): void

public function reset(): void
{
self::$mountMethods = [];
$this->mountMethods = [];
}
}

0 comments on commit 0acc77c

Please sign in to comment.