Yii2 framework backup
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

222 lines
6.1 KiB

<?php
/**
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace yii\twig;
use yii\base\InvalidCallException;
use yii\helpers\Inflector;
use yii\helpers\StringHelper;
use yii\helpers\Url;
/**
* Extension provides Yii-specific syntax for Twig templates.
*
* @author Andrey Grachov <andrey.grachov@gmail.com>
* @author Alexander Makarov <sam@rmcreative.ru>
*/
class Extension extends \Twig_Extension
{
/**
* @var array used namespaces
*/
protected $namespaces = [];
/**
* @var array used class aliases
*/
protected $aliases = [];
/**
* @var array used widgets
*/
protected $widgets = [];
/**
* Creates new instance
*
* @param array $uses namespaces and classes to use in the template
*/
public function __construct(array $uses = [])
{
$this->addUses($uses);
}
/**
* @inheritdoc
*/
public function getNodeVisitors()
{
return [
new Optimizer(),
];
}
/**
* @inheritdoc
*/
public function getFunctions()
{
$options = [
'is_safe' => ['html'],
];
$functions = [
new \Twig_SimpleFunction('use', [$this, 'addUses'], $options),
new \Twig_SimpleFunction('*_begin', [$this, 'beginWidget'], $options),
new \Twig_SimpleFunction('*_end', [$this, 'endWidget'], $options),
new \Twig_SimpleFunction('widget_end', [$this, 'endWidget'], $options),
new \Twig_SimpleFunction('*_widget', [$this, 'widget'], $options),
new \Twig_SimpleFunction('path', [$this, 'path']),
new \Twig_SimpleFunction('url', [$this, 'url']),
new \Twig_SimpleFunction('void', function(){}),
new \Twig_SimpleFunction('set', [$this, 'setProperty']),
];
$options = array_merge($options, [
'needs_context' => true,
]);
$functions[] = new \Twig_SimpleFunction('register_*', [$this, 'registerAsset'], $options);
foreach (['begin_page', 'end_page', 'begin_body', 'end_body', 'head'] as $helper) {
$functions[] = new \Twig_SimpleFunction($helper, [$this, 'viewHelper'], $options);
}
return $functions;
}
public function registerAsset($context, $asset)
{
return $this->resolveAndCall($asset, 'register', [
isset($context['this']) ? $context['this'] : null,
]);
}
public function beginWidget($widget, $config = [])
{
$widget = $this->resolveClassName($widget);
$this->widgets[] = $widget;
return $this->call($widget, 'begin', [
$config,
]);
}
public function endWidget($widget = null)
{
if ($widget === null) {
if (empty($this->widgets)) {
throw new InvalidCallException('Unexpected end_widget() call. A matching begin_widget() is not found.');
}
$this->call(array_pop($this->widgets), 'end');
} else {
array_pop($this->widgets);
$this->resolveAndCall($widget, 'end');
}
}
public function widget($widget, $config = [])
{
return $this->resolveAndCall($widget, 'widget', [
$config,
]);
}
public function viewHelper($context, $name = null)
{
if ($name !== null && isset($context['this'])) {
$this->call($context['this'], Inflector::variablize($name));
}
}
public function resolveAndCall($className, $method, $arguments = null)
{
return $this->call($this->resolveClassName($className), $method, $arguments);
}
public function call($className, $method, $arguments = null)
{
$callable = [$className, $method];
if ($arguments === null) {
return call_user_func($callable);
} else {
return call_user_func_array($callable, $arguments);
}
}
public function resolveClassName($className)
{
$className = Inflector::id2camel($className, '_');
if (isset($this->aliases[$className])) {
return $this->aliases[$className];
}
foreach ($this->namespaces as $namespace) {
$resolvedClassName = $namespace . '\\' . $className;
if (class_exists($resolvedClassName)) {
return $this->aliases[$className] = $resolvedClassName;
}
}
return $className;
}
public function addUses($args)
{
foreach ((array) $args as $key => $value) {
$value = str_replace('/', '\\', $value);
if (is_int($key)) {
// namespace or class import
if (class_exists($value)) {
// class import
$this->aliases[StringHelper::basename($value)] = $value;
} else {
// namespace
$this->namespaces[] = $value;
}
} else {
// aliased class import
$this->aliases[$key] = $value;
}
}
}
/**
* Generates relative URL
*
* @param string $path the parameter to be used to generate a valid URL
* @param array $args arguments
* @return string the generated relative URL
*/
public function path($path, $args = [])
{
if ($args !== []) {
$path = array_merge([$path], $args);
}
return Url::to($path);
}
/**
* Generates absolute URL
*
* @param string $path the parameter to be used to generate a valid URL
* @param array $args arguments
* @return string the generated absolute URL
*/
public function url($path, $args = [])
{
if ($args !== []) {
$path = array_merge([$path], $args);
}
return Url::to($path, true);
}
public function setProperty($object, $property, $value)
{
$object->$property = $value;
}
/**
* @inheritdoc
*/
public function getName()
{
return 'yii2-twig';
}
}