fenom/src/Fenom/Render.php

255 lines
5.4 KiB
PHP
Raw Permalink Normal View History

2013-01-25 18:36:16 +04:00
<?php
2013-04-28 11:33:36 +04:00
/*
2013-06-28 11:53:53 +04:00
* This file is part of Fenom.
2013-04-28 11:33:36 +04:00
*
* (c) 2013 Ivan Shalganov
*
2013-04-28 18:08:57 +04:00
* For the full copyright and license information, please view the license.md
2013-04-28 11:33:36 +04:00
* file that was distributed with this source code.
*/
2013-06-28 11:53:53 +04:00
namespace Fenom;
2014-02-27 16:30:44 +04:00
2013-06-28 11:53:53 +04:00
use Fenom;
2023-02-23 23:50:12 +03:00
use Fenom\Error\TemplateException;
2013-01-25 18:36:16 +04:00
/**
* Primitive template
2013-07-04 01:28:10 +04:00
* @author Ivan Shalganov <a.cobest@gmail.com>
2013-01-25 18:36:16 +04:00
*/
2013-07-29 14:58:14 +04:00
class Render extends \ArrayObject
{
2023-02-06 00:18:18 +03:00
private static array $_props = [
2014-05-06 14:22:58 +04:00
"name" => "runtime",
2013-02-13 20:51:27 +04:00
"base_name" => "",
2014-05-06 14:22:58 +04:00
"scm" => false,
"time" => 0,
2023-02-06 00:18:18 +03:00
"depends" => [],
"macros" => []
];
/**
2023-02-07 01:49:54 +03:00
* @var \Closure|null
*/
2023-02-07 01:49:54 +03:00
protected ?\Closure $_code = null;
2013-01-25 18:36:16 +04:00
/**
* Template name
* @var string
*/
2023-02-06 00:18:18 +03:00
protected mixed $_name = 'runtime';
2013-04-28 11:33:36 +04:00
/**
* Provider's schema
2023-02-06 00:18:18 +03:00
* @var string|null
2013-04-28 11:33:36 +04:00
*/
2023-02-07 01:49:54 +03:00
protected ?string $_scm = null;
2013-04-28 11:33:36 +04:00
/**
* Basic template name
* @var string
*/
2023-02-06 00:18:18 +03:00
protected string $_base_name = 'runtime';
2013-01-25 18:36:16 +04:00
/**
2013-06-28 11:53:53 +04:00
* @var Fenom
2013-01-25 18:36:16 +04:00
*/
2023-02-06 00:18:18 +03:00
protected Fenom $_fenom;
2013-01-25 18:36:16 +04:00
/**
* Timestamp of compilation
* @var float
2013-01-25 18:36:16 +04:00
*/
2023-02-06 00:18:18 +03:00
protected float $_time = 0.0;
2013-04-28 11:33:36 +04:00
/**
* @var array depends list
*/
2023-02-06 00:18:18 +03:00
protected array $_depends = [];
2013-01-25 18:36:16 +04:00
2013-04-28 11:33:36 +04:00
/**
2013-07-05 00:02:24 +04:00
* @var int template options (see Fenom options)
2013-04-28 11:33:36 +04:00
*/
2023-02-06 00:18:18 +03:00
protected int $_options = 0;
2013-04-04 10:56:44 +04:00
2013-01-25 18:36:16 +04:00
/**
2013-02-13 20:51:27 +04:00
* Template provider
* @var ProviderInterface
2013-01-25 18:36:16 +04:00
*/
2023-02-06 00:18:18 +03:00
protected ProviderInterface $_provider;
2013-01-25 18:36:16 +04:00
2013-08-22 00:03:20 +04:00
/**
* @var \Closure[]
*/
2023-02-06 00:18:18 +03:00
protected array $_macros;
2013-08-22 00:03:20 +04:00
2013-01-25 18:36:16 +04:00
/**
2013-06-28 11:53:53 +04:00
* @param Fenom $fenom
2023-02-06 00:18:18 +03:00
* @param \Closure $code template body
2013-02-13 20:51:27 +04:00
* @param array $props
2013-01-25 18:36:16 +04:00
*/
2013-07-29 14:58:14 +04:00
public function __construct(Fenom $fenom, \Closure $code, array $props = array())
{
2023-02-06 00:18:18 +03:00
parent::__construct();
2013-06-28 11:53:53 +04:00
$this->_fenom = $fenom;
2013-02-13 20:51:27 +04:00
$props += self::$_props;
2014-05-06 14:22:58 +04:00
$this->_name = $props["name"];
2013-09-14 11:24:23 +04:00
$this->_base_name = $props["base_name"];
2014-05-06 14:22:58 +04:00
$this->_scm = $props["scm"];
$this->_time = $props["time"];
$this->_depends = $props["depends"];
$this->_macros = $props["macros"];
$this->_code = $code;
}
2013-01-25 18:36:16 +04:00
/**
* Get template storage
2013-07-29 14:53:21 +04:00
* @return \Fenom
2013-01-25 18:36:16 +04:00
*/
2023-02-06 00:18:18 +03:00
public function getStorage(): Fenom
2013-07-29 14:58:14 +04:00
{
2013-06-28 11:53:53 +04:00
return $this->_fenom;
2013-01-25 18:36:16 +04:00
}
2013-07-29 14:53:21 +04:00
/**
2023-02-06 00:18:18 +03:00
* Get list of dependencies.
2013-07-29 14:53:21 +04:00
* @return array
*/
2023-02-06 00:18:18 +03:00
public function getDepends(): array
2013-07-29 14:58:14 +04:00
{
2013-02-15 01:49:26 +04:00
return $this->_depends;
}
2013-07-29 14:53:21 +04:00
/**
* Get schema name
2023-02-06 00:18:18 +03:00
* @return string|null
2013-07-29 14:53:21 +04:00
*/
2023-02-06 00:18:18 +03:00
public function getScm(): ?string
2013-07-29 14:58:14 +04:00
{
2013-02-13 20:51:27 +04:00
return $this->_scm;
}
2013-07-29 14:53:21 +04:00
/**
* Get provider of template source
* @return ProviderInterface
*/
2023-02-06 00:18:18 +03:00
public function getProvider(): ProviderInterface
2013-07-29 14:58:14 +04:00
{
return $this->_fenom->getProvider($this->_scm);
2013-02-13 20:51:27 +04:00
}
2013-07-29 14:53:21 +04:00
/**
* Get name without schema
* @return string
*/
2023-02-06 00:18:18 +03:00
public function getBaseName(): string
2013-07-29 14:58:14 +04:00
{
2013-02-13 20:51:27 +04:00
return $this->_base_name;
}
2013-07-29 14:53:21 +04:00
/**
* Get parse options
* @return int
*/
2023-02-06 00:18:18 +03:00
public function getOptions(): int
2013-07-29 14:58:14 +04:00
{
2013-04-04 10:56:44 +04:00
return $this->_options;
}
2013-01-25 18:36:16 +04:00
/**
* @return string
*/
2013-07-29 14:58:14 +04:00
public function __toString()
{
return $this->_name;
}
2013-01-25 18:36:16 +04:00
/**
* Get template name
* @return string
*/
2023-02-06 00:18:18 +03:00
public function getName(): string
2013-07-29 14:58:14 +04:00
{
2013-01-25 18:36:16 +04:00
return $this->_name;
}
2013-07-29 14:58:14 +04:00
public function getTime()
{
return $this->_time;
}
2013-01-25 18:36:16 +04:00
/**
* Validate template
2013-01-25 18:36:16 +04:00
* @return bool
*/
2023-02-06 00:18:18 +03:00
public function isValid(): bool
2013-07-29 14:58:14 +04:00
{
2015-01-06 23:42:54 +03:00
foreach ($this->_depends as $scm => $templates) {
$provider = $this->_fenom->getProvider($scm);
if(count($templates) === 1) {
if ($provider->getLastModified(key($templates)) !== $this->_time) {
return false;
}
} else {
2013-07-29 14:58:14 +04:00
if (!$provider->verify($templates)) {
return false;
}
}
}
return true;
2013-01-25 18:36:16 +04:00
}
2013-08-05 13:07:16 +04:00
/**
* Get internal macro
* @param $name
* @throws \RuntimeException
2013-08-05 13:07:16 +04:00
* @return mixed
*/
2023-02-06 00:18:18 +03:00
public function getMacro($name): mixed
2013-08-11 19:55:30 +04:00
{
2013-09-02 17:40:58 +04:00
if (empty($this->_macros[$name])) {
2014-04-17 23:27:59 +04:00
throw new \RuntimeException('macro ' . $name . ' not found');
2013-08-22 00:03:20 +04:00
}
2013-08-05 13:07:16 +04:00
return $this->_macros[$name];
}
2013-01-25 18:36:16 +04:00
/**
* Execute template and write into output
* @param array $values for template
2023-02-06 00:18:18 +03:00
* @return array
2023-02-23 23:50:12 +03:00
* @throws TemplateException
2013-01-25 18:36:16 +04:00
*/
2023-02-06 00:18:18 +03:00
public function display(array $values): array
2013-07-29 14:58:14 +04:00
{
2023-02-23 23:50:12 +03:00
try {
$this->_code->__invoke($values, $this);
} catch (\Throwable $e) {
throw new Fenom\Error\TemplateException("unhandled exception in the template `{$this->getName()}`: {$e->getMessage()}", 0, $e);
}
return $values;
}
2013-01-25 18:36:16 +04:00
/**
* Execute template and return result as string
* @param array $values for template
* @return string
* @throws \Exception
*/
2023-02-06 00:18:18 +03:00
public function fetch(array $values): string
2013-07-29 14:58:14 +04:00
{
2013-01-25 18:36:16 +04:00
ob_start();
try {
$this->display($values);
return ob_get_clean();
} catch (\Exception $e) {
ob_end_clean();
throw $e;
}
}
/**
* Stub
2023-02-06 00:18:18 +03:00
* @param string $method
* @param mixed $args
2013-01-25 18:36:16 +04:00
* @throws \BadMethodCallException
*/
2023-02-06 00:18:18 +03:00
public function __call(string $method, mixed $args)
2013-07-29 14:58:14 +04:00
{
throw new \BadMethodCallException("Unknown method " . $method);
}
2013-01-25 18:36:16 +04:00
}