<?php namespace Syna; class Engine { protected $sharedData = []; /** @var HelperLocator */ protected $helperLocator; /** @var ViewLocator */ protected $viewLocator; /** @var ViewLocator[] */ protected $namedLocators = []; /** * Engine constructor. * @param ViewLocator $viewLocator * @param HelperLocator $helperLocator * @param ViewLocator $layoutLocator */ public function __construct( ViewLocator $viewLocator, HelperLocator $helperLocator = null, ViewLocator $layoutLocator = null ) { $this->viewLocator = $viewLocator; $this->helperLocator = $helperLocator ?? new HelperLocator(); !$layoutLocator || $this->namedLocators['layout'] = $layoutLocator; } public function addLocator(string $name, HelperLocator $locator): self { $this->namedLocators[$name] = $locator; return $this; } public function addSharedData(array $data): self { $this->sharedData = array_merge($this->sharedData, $data); return $this; } public function getSharedData() { return $this->sharedData; } public function view(string $name, array $data = []): View { $viewLocator = $this->viewLocator; if (strpos($name, '::', 1) !== false) { list($locatorName, $name) = explode('::', $name); if (!isset($this->namedLocators[$locatorName])) { throw new \LogicException('No locator for ' . $locatorName . ' defined'); } $viewLocator = $this->namedLocators[$locatorName]; } if (!$viewLocator->has($name)) { throw new \Exception('View ' . $name . ' not found'); } return new View($this, $viewLocator->getPath($name), $data); } public function render(string $name, array $data = [], string $layout = null): string { $view = $this->view($name, $data); $content = $view->render(); if ($layout && isset($this->namedLocators['layout'])) { $layout = $this->view('layout::' . $layout); $layout->setSections(array_merge($view->getSections(), ['content' => $content])); $content = $layout->render(); } return $content; } public function helper(View $view, $function, ...$arguments) { if ($this->helperLocator->has($function)) { $helper = $this->helperLocator->getHelper($function); $helper->setView($view); /** @noinspection PhpMethodParametersCountMismatchInspection */ return $helper(...$arguments); } elseif (is_callable($function)) { return call_user_func($function, ...$arguments); } throw new \LogicException('$function has to be callable or a registered view helper'); } }