<?php namespace Studip; use Flexi\Template; use Stringable; final class VueApp implements Stringable { public static function create(string $base_component): VueApp { return new self($base_component); } private array $components = []; private array $props = []; private array $stores = []; private array $storeData = []; private function __construct(private readonly string $base_component) { } public function withComponents(string ...$components): VueApp { $clone = clone $this; foreach ($components as $component) { $clone = $clone->withAddedComponent($component); } return $clone; } public function withAddedComponent(string $component): VueApp { $clone = clone $this; if (!in_array($component, $clone->components)) { $clone->components[] = $component; } return $clone; } public function getBaseComponent(): string { return $this->base_component; } public function withProps(array $props): VueApp { $clone = clone $this; $clone->props = $props; return $clone; } public function getProps(): array { return $this->props; } public function withStore(?string $store, ?string $index = null, ?array $data = null): VueApp { $clone = clone $this; $clone->stores[$index ?? $store] = $store; if ($data !== null) { $clone->storeData[$index ?? $store] = $data; } return $clone; } public function getStores(): array { return $this->stores; } public function getStoreData(): array { return $this->storeData; } public function getTemplate(): Template { $template = $GLOBALS['template_factory']->open('vue-app.php'); $template->attributes = [ 'data-vue-app' => json_encode([ 'components' => [ $this->base_component, ...$this->components ], 'stores' => $this->stores, ]), 'is' => basename($this->base_component), ...$this->getPreparedProps(), ]; $template->storeData = $this->storeData; return $template; } private function getPreparedProps(): array { $result = []; foreach ($this->props as $name => $value) { $name = ltrim($name, ':'); $result[":{$name}"] = json_encode($value); } return $result; } public function render(): string { return $this->getTemplate()->render(); } public function __toString(): string { return $this->render(); } }