upgraded dependencies
This commit is contained in:
55
vendor/laravel/framework/src/Illuminate/View/AnonymousComponent.php
vendored
Normal file
55
vendor/laravel/framework/src/Illuminate/View/AnonymousComponent.php
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\View;
|
||||
|
||||
class AnonymousComponent extends Component
|
||||
{
|
||||
/**
|
||||
* The component view.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $view;
|
||||
|
||||
/**
|
||||
* The component data.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $data = [];
|
||||
|
||||
/**
|
||||
* Create a new anonymous component instance.
|
||||
*
|
||||
* @param string $view
|
||||
* @param array $data
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($view, $data)
|
||||
{
|
||||
$this->view = $view;
|
||||
$this->data = $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the view / view contents that represent the component.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function render()
|
||||
{
|
||||
return $this->view;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the data that should be supplied to the view.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function data()
|
||||
{
|
||||
$this->attributes = $this->attributes ?: new ComponentAttributeBag;
|
||||
|
||||
return $this->data + ['attributes' => $this->attributes];
|
||||
}
|
||||
}
|
||||
@@ -45,6 +45,13 @@ class BladeCompiler extends Compiler implements CompilerInterface
|
||||
*/
|
||||
protected $conditions = [];
|
||||
|
||||
/**
|
||||
* All of the registered precompilers.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $precompilers = [];
|
||||
|
||||
/**
|
||||
* The file currently being compiled.
|
||||
*
|
||||
@@ -58,7 +65,7 @@ class BladeCompiler extends Compiler implements CompilerInterface
|
||||
* @var array
|
||||
*/
|
||||
protected $compilers = [
|
||||
'Comments',
|
||||
// 'Comments',
|
||||
'Extensions',
|
||||
'Statements',
|
||||
'Echos',
|
||||
@@ -106,6 +113,20 @@ class BladeCompiler extends Compiler implements CompilerInterface
|
||||
*/
|
||||
protected $rawBlocks = [];
|
||||
|
||||
/**
|
||||
* The array of class component aliases and their class names.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $classComponentAliases = [];
|
||||
|
||||
/**
|
||||
* Indicates if component tags should be compiled.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $compilesComponentTags = true;
|
||||
|
||||
/**
|
||||
* Compile the view at the given path.
|
||||
*
|
||||
@@ -194,7 +215,16 @@ class BladeCompiler extends Compiler implements CompilerInterface
|
||||
{
|
||||
[$this->footer, $result] = [[], ''];
|
||||
|
||||
$value = $this->storeUncompiledBlocks($value);
|
||||
// First we will compile the Blade component tags. This is a precompile style
|
||||
// step which compiles the component Blade tags into @component directives
|
||||
// that may be used by Blade. Then we should call any other precompilers.
|
||||
$value = $this->compileComponentTags(
|
||||
$this->compileComments($this->storeUncompiledBlocks($value))
|
||||
);
|
||||
|
||||
foreach ($this->precompilers as $precompiler) {
|
||||
$value = call_user_func($precompiler, $value);
|
||||
}
|
||||
|
||||
// Here we will loop through all of the tokens returned by the Zend lexer and
|
||||
// parse each one into the corresponding valid PHP. We will then have this
|
||||
@@ -275,6 +305,23 @@ class BladeCompiler extends Compiler implements CompilerInterface
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the component tags.
|
||||
*
|
||||
* @param string $value
|
||||
* @return string
|
||||
*/
|
||||
protected function compileComponentTags($value)
|
||||
{
|
||||
if (! $this->compilesComponentTags) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
return (new ComponentTagCompiler(
|
||||
$this->classComponentAliases, $this
|
||||
))->compile($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace the raw placeholders with the original code stored in the raw blocks.
|
||||
*
|
||||
@@ -311,8 +358,8 @@ class BladeCompiler extends Compiler implements CompilerInterface
|
||||
*/
|
||||
protected function addFooters($result)
|
||||
{
|
||||
return ltrim($result, PHP_EOL)
|
||||
.PHP_EOL.implode(PHP_EOL, array_reverse($this->footer));
|
||||
return ltrim($result, "\n")
|
||||
."\n".implode("\n", array_reverse($this->footer));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -481,6 +528,63 @@ class BladeCompiler extends Compiler implements CompilerInterface
|
||||
return call_user_func($this->conditions[$name], ...$parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a class-based component alias directive.
|
||||
*
|
||||
* @param string $class
|
||||
* @param string|null $alias
|
||||
* @param string $prefix
|
||||
* @return void
|
||||
*/
|
||||
public function component($class, $alias = null, $prefix = '')
|
||||
{
|
||||
if (! is_null($alias) && Str::contains($alias, '\\')) {
|
||||
[$class, $alias] = [$alias, $class];
|
||||
}
|
||||
|
||||
if (is_null($alias)) {
|
||||
$alias = Str::contains($class, '\\View\\Components\\')
|
||||
? collect(explode('\\', Str::after($class, '\\View\\Components\\')))->map(function ($segment) {
|
||||
return Str::kebab($segment);
|
||||
})->implode(':')
|
||||
: Str::kebab(class_basename($class));
|
||||
}
|
||||
|
||||
if (! empty($prefix)) {
|
||||
$alias = $prefix.'-'.$alias;
|
||||
}
|
||||
|
||||
$this->classComponentAliases[$alias] = $class;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register an array of class-based components.
|
||||
*
|
||||
* @param array $components
|
||||
* @param string $prefix
|
||||
* @return void
|
||||
*/
|
||||
public function components(array $components, $prefix = '')
|
||||
{
|
||||
foreach ($components as $key => $value) {
|
||||
if (is_numeric($key)) {
|
||||
static::component($value, null, $prefix);
|
||||
} else {
|
||||
static::component($key, $value, $prefix);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the registered class component aliases.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getClassComponentAliases()
|
||||
{
|
||||
return $this->classComponentAliases;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a component alias directive.
|
||||
*
|
||||
@@ -488,7 +592,7 @@ class BladeCompiler extends Compiler implements CompilerInterface
|
||||
* @param string|null $alias
|
||||
* @return void
|
||||
*/
|
||||
public function component($path, $alias = null)
|
||||
public function aliasComponent($path, $alias = null)
|
||||
{
|
||||
$alias = $alias ?: Arr::last(explode('.', $path));
|
||||
|
||||
@@ -511,6 +615,18 @@ class BladeCompiler extends Compiler implements CompilerInterface
|
||||
* @return void
|
||||
*/
|
||||
public function include($path, $alias = null)
|
||||
{
|
||||
return $this->aliasInclude($path, $alias);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register an include alias directive.
|
||||
*
|
||||
* @param string $path
|
||||
* @param string|null $alias
|
||||
* @return void
|
||||
*/
|
||||
public function aliasInclude($path, $alias = null)
|
||||
{
|
||||
$alias = $alias ?: Arr::last(explode('.', $path));
|
||||
|
||||
@@ -549,6 +665,17 @@ class BladeCompiler extends Compiler implements CompilerInterface
|
||||
return $this->customDirectives;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a new precompiler.
|
||||
*
|
||||
* @param callable $precompiler
|
||||
* @return void
|
||||
*/
|
||||
public function precompiler(callable $precompiler)
|
||||
{
|
||||
$this->precompilers[] = $precompiler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the echo format to be used by the compiler.
|
||||
*
|
||||
@@ -579,4 +706,14 @@ class BladeCompiler extends Compiler implements CompilerInterface
|
||||
{
|
||||
$this->setEchoFormat('e(%s, false)');
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicate that component tags should not be compiled.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function withoutComponentTags()
|
||||
{
|
||||
$this->compilesComponentTags = false;
|
||||
}
|
||||
}
|
||||
|
||||
488
vendor/laravel/framework/src/Illuminate/View/Compilers/ComponentTagCompiler.php
vendored
Normal file
488
vendor/laravel/framework/src/Illuminate/View/Compilers/ComponentTagCompiler.php
vendored
Normal file
@@ -0,0 +1,488 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\View\Compilers;
|
||||
|
||||
use Illuminate\Container\Container;
|
||||
use Illuminate\Contracts\Foundation\Application;
|
||||
use Illuminate\Contracts\View\Factory;
|
||||
use Illuminate\Filesystem\Filesystem;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\View\AnonymousComponent;
|
||||
use Illuminate\View\ViewFinderInterface;
|
||||
use InvalidArgumentException;
|
||||
use ReflectionClass;
|
||||
|
||||
/**
|
||||
* @author Spatie bvba <info@spatie.be>
|
||||
* @author Taylor Otwell <taylor@laravel.com>
|
||||
*/
|
||||
class ComponentTagCompiler
|
||||
{
|
||||
/**
|
||||
* The Blade compiler instance.
|
||||
*
|
||||
* @var \Illuminate\View\Compilers\BladeCompiler
|
||||
*/
|
||||
protected $blade;
|
||||
|
||||
/**
|
||||
* The component class aliases.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $aliases = [];
|
||||
|
||||
/**
|
||||
* The "bind:" attributes that have been compiled for the current component.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $boundAttributes = [];
|
||||
|
||||
/**
|
||||
* Create new component tag compiler.
|
||||
*
|
||||
* @param array $aliases
|
||||
* @param \Illuminate\View\Compilers\BladeCompiler|null
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(array $aliases = [], ?BladeCompiler $blade = null)
|
||||
{
|
||||
$this->aliases = $aliases;
|
||||
|
||||
$this->blade = $blade ?: new BladeCompiler(new Filesystem, sys_get_temp_dir());
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the component and slot tags within the given string.
|
||||
*
|
||||
* @param string $value
|
||||
* @return string
|
||||
*/
|
||||
public function compile(string $value)
|
||||
{
|
||||
$value = $this->compileSlots($value);
|
||||
|
||||
return $this->compileTags($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the tags within the given string.
|
||||
*
|
||||
* @param string $value
|
||||
* @return string
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function compileTags(string $value)
|
||||
{
|
||||
$value = $this->compileSelfClosingTags($value);
|
||||
$value = $this->compileOpeningTags($value);
|
||||
$value = $this->compileClosingTags($value);
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the opening tags within the given string.
|
||||
*
|
||||
* @param string $value
|
||||
* @return string
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
protected function compileOpeningTags(string $value)
|
||||
{
|
||||
$pattern = "/
|
||||
<
|
||||
\s*
|
||||
x[-\:]([\w\-\:\.]*)
|
||||
(?<attributes>
|
||||
(?:
|
||||
\s+
|
||||
[\w\-:.@]+
|
||||
(
|
||||
=
|
||||
(?:
|
||||
\\\"[^\\\"]*\\\"
|
||||
|
|
||||
\'[^\']*\'
|
||||
|
|
||||
[^\'\\\"=<>]+
|
||||
)
|
||||
)
|
||||
?)*
|
||||
\s*
|
||||
)
|
||||
(?<![\/=\-])
|
||||
>
|
||||
/x";
|
||||
|
||||
return preg_replace_callback($pattern, function (array $matches) {
|
||||
$this->boundAttributes = [];
|
||||
|
||||
$attributes = $this->getAttributesFromAttributeString($matches['attributes']);
|
||||
|
||||
return $this->componentString($matches[1], $attributes);
|
||||
}, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the self-closing tags within the given string.
|
||||
*
|
||||
* @param string $value
|
||||
* @return string
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
protected function compileSelfClosingTags(string $value)
|
||||
{
|
||||
$pattern = "/
|
||||
<
|
||||
\s*
|
||||
x[-\:]([\w\-\:\.]*)
|
||||
\s*
|
||||
(?<attributes>
|
||||
(?:
|
||||
\s+
|
||||
[\w\-:.@]+
|
||||
(
|
||||
=
|
||||
(?:
|
||||
\\\"[^\\\"]*\\\"
|
||||
|
|
||||
\'[^\']*\'
|
||||
|
|
||||
[^\'\\\"=<>]+
|
||||
)
|
||||
)?
|
||||
)*
|
||||
\s*
|
||||
)
|
||||
\/>
|
||||
/x";
|
||||
|
||||
return preg_replace_callback($pattern, function (array $matches) {
|
||||
$this->boundAttributes = [];
|
||||
|
||||
$attributes = $this->getAttributesFromAttributeString($matches['attributes']);
|
||||
|
||||
return $this->componentString($matches[1], $attributes)."\n@endcomponentClass ";
|
||||
}, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the Blade component string for the given component and attributes.
|
||||
*
|
||||
* @param string $component
|
||||
* @param array $attributes
|
||||
* @return string
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
protected function componentString(string $component, array $attributes)
|
||||
{
|
||||
$class = $this->componentClass($component);
|
||||
|
||||
[$data, $attributes] = $this->partitionDataAndAttributes($class, $attributes);
|
||||
|
||||
$data = $data->mapWithKeys(function ($value, $key) {
|
||||
return [Str::camel($key) => $value];
|
||||
});
|
||||
|
||||
// If the component doesn't exists as a class we'll assume it's a class-less
|
||||
// component and pass the component as a view parameter to the data so it
|
||||
// can be accessed within the component and we can render out the view.
|
||||
if (! class_exists($class)) {
|
||||
$parameters = [
|
||||
'view' => "'$class'",
|
||||
'data' => '['.$this->attributesToString($data->all(), $escapeBound = false).']',
|
||||
];
|
||||
|
||||
$class = AnonymousComponent::class;
|
||||
} else {
|
||||
$parameters = $data->all();
|
||||
}
|
||||
|
||||
return " @component('{$class}', '{$component}', [".$this->attributesToString($parameters, $escapeBound = false).'])
|
||||
<?php $component->withAttributes(['.$this->attributesToString($attributes->all()).']); ?>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the component class for a given component alias.
|
||||
*
|
||||
* @param string $component
|
||||
* @return string
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
protected function componentClass(string $component)
|
||||
{
|
||||
$viewFactory = Container::getInstance()->make(Factory::class);
|
||||
|
||||
if (isset($this->aliases[$component])) {
|
||||
if (class_exists($alias = $this->aliases[$component])) {
|
||||
return $alias;
|
||||
}
|
||||
|
||||
if ($viewFactory->exists($alias)) {
|
||||
return $alias;
|
||||
}
|
||||
|
||||
throw new InvalidArgumentException(
|
||||
"Unable to locate class or view [{$alias}] for component [{$component}]."
|
||||
);
|
||||
}
|
||||
|
||||
if (class_exists($class = $this->guessClassName($component))) {
|
||||
return $class;
|
||||
}
|
||||
|
||||
if ($viewFactory->exists($view = $this->guessViewName($component))) {
|
||||
return $view;
|
||||
}
|
||||
|
||||
throw new InvalidArgumentException(
|
||||
"Unable to locate a class or view for component [{$component}]."
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Guess the class name for the given component.
|
||||
*
|
||||
* @param string $component
|
||||
* @return string
|
||||
*/
|
||||
public function guessClassName(string $component)
|
||||
{
|
||||
$namespace = Container::getInstance()
|
||||
->make(Application::class)
|
||||
->getNamespace();
|
||||
|
||||
$componentPieces = array_map(function ($componentPiece) {
|
||||
return ucfirst(Str::camel($componentPiece));
|
||||
}, explode('.', $component));
|
||||
|
||||
return $namespace.'View\\Components\\'.implode('\\', $componentPieces);
|
||||
}
|
||||
|
||||
/**
|
||||
* Guess the view name for the given component.
|
||||
*
|
||||
* @param string $name
|
||||
* @return string
|
||||
*/
|
||||
public function guessViewName($name)
|
||||
{
|
||||
$prefix = 'components.';
|
||||
|
||||
$delimiter = ViewFinderInterface::HINT_PATH_DELIMITER;
|
||||
|
||||
if (Str::contains($name, $delimiter)) {
|
||||
return Str::replaceFirst($delimiter, $delimiter.$prefix, $name);
|
||||
}
|
||||
|
||||
return $prefix.$name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Partition the data and extra attributes from the given array of attributes.
|
||||
*
|
||||
* @param string $class
|
||||
* @param array $attributes
|
||||
* @return array
|
||||
*/
|
||||
protected function partitionDataAndAttributes($class, array $attributes)
|
||||
{
|
||||
// If the class doesn't exists, we'll assume it's a class-less component and
|
||||
// return all of the attributes as both data and attributes since we have
|
||||
// now way to partition them. The user can exclude attributes manually.
|
||||
if (! class_exists($class)) {
|
||||
return [collect($attributes), collect($attributes)];
|
||||
}
|
||||
|
||||
$constructor = (new ReflectionClass($class))->getConstructor();
|
||||
|
||||
$parameterNames = $constructor
|
||||
? collect($constructor->getParameters())->map->getName()->all()
|
||||
: [];
|
||||
|
||||
return collect($attributes)->partition(function ($value, $key) use ($parameterNames) {
|
||||
return in_array(Str::camel($key), $parameterNames);
|
||||
})->all();
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the closing tags within the given string.
|
||||
*
|
||||
* @param string $value
|
||||
* @return string
|
||||
*/
|
||||
protected function compileClosingTags(string $value)
|
||||
{
|
||||
return preg_replace("/<\/\s*x[-\:][\w\-\:\.]*\s*>/", ' @endcomponentClass ', $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the slot tags within the given string.
|
||||
*
|
||||
* @param string $value
|
||||
* @return string
|
||||
*/
|
||||
public function compileSlots(string $value)
|
||||
{
|
||||
$value = preg_replace_callback('/<\s*x[\-\:]slot\s+(:?)name=(?<name>(\"[^\"]+\"|\\\'[^\\\']+\\\'|[^\s>]+))\s*>/', function ($matches) {
|
||||
$name = $this->stripQuotes($matches['name']);
|
||||
|
||||
if ($matches[1] !== ':') {
|
||||
$name = "'{$name}'";
|
||||
}
|
||||
|
||||
return " @slot({$name}) ";
|
||||
}, $value);
|
||||
|
||||
return preg_replace('/<\/\s*x[\-\:]slot[^>]*>/', ' @endslot', $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an array of attributes from the given attribute string.
|
||||
*
|
||||
* @param string $attributeString
|
||||
* @return array
|
||||
*/
|
||||
protected function getAttributesFromAttributeString(string $attributeString)
|
||||
{
|
||||
$attributeString = $this->parseBindAttributes($attributeString);
|
||||
|
||||
$pattern = '/
|
||||
(?<attribute>[\w\-:.@]+)
|
||||
(
|
||||
=
|
||||
(?<value>
|
||||
(
|
||||
\"[^\"]+\"
|
||||
|
|
||||
\\\'[^\\\']+\\\'
|
||||
|
|
||||
[^\s>]+
|
||||
)
|
||||
)
|
||||
)?
|
||||
/x';
|
||||
|
||||
if (! preg_match_all($pattern, $attributeString, $matches, PREG_SET_ORDER)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return collect($matches)->mapWithKeys(function ($match) {
|
||||
$attribute = $match['attribute'];
|
||||
$value = $match['value'] ?? null;
|
||||
|
||||
if (is_null($value)) {
|
||||
$value = 'true';
|
||||
|
||||
$attribute = Str::start($attribute, 'bind:');
|
||||
}
|
||||
|
||||
$value = $this->stripQuotes($value);
|
||||
|
||||
if (Str::startsWith($attribute, 'bind:')) {
|
||||
$attribute = Str::after($attribute, 'bind:');
|
||||
|
||||
$this->boundAttributes[$attribute] = true;
|
||||
} else {
|
||||
$value = "'".$this->compileAttributeEchos($value)."'";
|
||||
}
|
||||
|
||||
return [$attribute => $value];
|
||||
})->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the "bind" attributes in a given attribute string into their fully-qualified syntax.
|
||||
*
|
||||
* @param string $attributeString
|
||||
* @return string
|
||||
*/
|
||||
protected function parseBindAttributes(string $attributeString)
|
||||
{
|
||||
$pattern = "/
|
||||
(?:^|\s+) # start of the string or whitespace between attributes
|
||||
: # attribute needs to start with a semicolon
|
||||
([\w\-:.@]+) # match the actual attribute name
|
||||
= # only match attributes that have a value
|
||||
/xm";
|
||||
|
||||
return preg_replace($pattern, ' bind:$1=', $attributeString);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile any Blade echo statements that are present in the attribute string.
|
||||
*
|
||||
* These echo statements need to be converted to string concatenation statements.
|
||||
*
|
||||
* @param string $attributeString
|
||||
* @return string
|
||||
*/
|
||||
protected function compileAttributeEchos(string $attributeString)
|
||||
{
|
||||
$value = $this->blade->compileEchos($attributeString);
|
||||
|
||||
$value = $this->escapeSingleQuotesOutsideOfPhpBlocks($value);
|
||||
|
||||
$value = str_replace('<?php echo ', '\'.', $value);
|
||||
$value = str_replace('; ?>', '.\'', $value);
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Escape the single quotes in the given string that are outside of PHP blocks.
|
||||
*
|
||||
* @param string $value
|
||||
* @return string
|
||||
*/
|
||||
protected function escapeSingleQuotesOutsideOfPhpBlocks(string $value)
|
||||
{
|
||||
return collect(token_get_all($value))->map(function ($token) {
|
||||
if (! is_array($token)) {
|
||||
return $token;
|
||||
}
|
||||
|
||||
return $token[0] === T_INLINE_HTML
|
||||
? str_replace("'", "\\'", $token[1])
|
||||
: $token[1];
|
||||
})->implode('');
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert an array of attributes to a string.
|
||||
*
|
||||
* @param array $attributes
|
||||
* @param bool $escapeBound
|
||||
* @return string
|
||||
*/
|
||||
protected function attributesToString(array $attributes, $escapeBound = true)
|
||||
{
|
||||
return collect($attributes)
|
||||
->map(function (string $value, string $attribute) use ($escapeBound) {
|
||||
return $escapeBound && isset($this->boundAttributes[$attribute]) && $value !== 'true' && ! is_numeric($value)
|
||||
? "'{$attribute}' => \Illuminate\View\Compilers\BladeCompiler::sanitizeComponentAttribute({$value})"
|
||||
: "'{$attribute}' => {$value}";
|
||||
})
|
||||
->implode(',');
|
||||
}
|
||||
|
||||
/**
|
||||
* Strip any quotes from the given string.
|
||||
*
|
||||
* @param string $value
|
||||
* @return string
|
||||
*/
|
||||
public function stripQuotes(string $value)
|
||||
{
|
||||
return Str::startsWith($value, ['"', '\''])
|
||||
? substr($value, 1, -1)
|
||||
: $value;
|
||||
}
|
||||
}
|
||||
@@ -2,8 +2,17 @@
|
||||
|
||||
namespace Illuminate\View\Compilers\Concerns;
|
||||
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
trait CompilesComponents
|
||||
{
|
||||
/**
|
||||
* The component name hash stack.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected static $componentHashStack = [];
|
||||
|
||||
/**
|
||||
* Compile the component statements into valid PHP.
|
||||
*
|
||||
@@ -12,9 +21,54 @@ trait CompilesComponents
|
||||
*/
|
||||
protected function compileComponent($expression)
|
||||
{
|
||||
[$component, $alias, $data] = strpos($expression, ',') !== false
|
||||
? array_map('trim', explode(',', trim($expression, '()'), 3)) + ['', '', '']
|
||||
: [trim($expression, '()'), '', ''];
|
||||
|
||||
$component = trim($component, '\'"');
|
||||
|
||||
$hash = static::newComponentHash($component);
|
||||
|
||||
if (Str::contains($component, ['::class', '\\'])) {
|
||||
return static::compileClassComponentOpening($component, $alias, $data, $hash);
|
||||
}
|
||||
|
||||
return "<?php \$__env->startComponent{$expression}; ?>";
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a new component hash for a component name.
|
||||
*
|
||||
* @param string $component
|
||||
* @return string
|
||||
*/
|
||||
public static function newComponentHash(string $component)
|
||||
{
|
||||
static::$componentHashStack[] = $hash = sha1($component);
|
||||
|
||||
return $hash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile a class component opening.
|
||||
*
|
||||
* @param string $component
|
||||
* @param string $alias
|
||||
* @param string $data
|
||||
* @param string $hash
|
||||
* @return string
|
||||
*/
|
||||
public static function compileClassComponentOpening(string $component, string $alias, string $data, string $hash)
|
||||
{
|
||||
return implode("\n", [
|
||||
'<?php if (isset($component)) { $__componentOriginal'.$hash.' = $component; } ?>',
|
||||
'<?php $component = $__env->getContainer()->make('.Str::finish($component, '::class').', '.($data ?: '[]').'); ?>',
|
||||
'<?php $component->withName('.$alias.'); ?>',
|
||||
'<?php if ($component->shouldRender()): ?>',
|
||||
'<?php $__env->startComponent($component->resolveView(), $component->data()); ?>',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the end-component statements into valid PHP.
|
||||
*
|
||||
@@ -22,7 +76,27 @@ trait CompilesComponents
|
||||
*/
|
||||
protected function compileEndComponent()
|
||||
{
|
||||
return '<?php echo $__env->renderComponent(); ?>';
|
||||
$hash = array_pop(static::$componentHashStack);
|
||||
|
||||
return implode("\n", [
|
||||
'<?php if (isset($__componentOriginal'.$hash.')): ?>',
|
||||
'<?php $component = $__componentOriginal'.$hash.'; ?>',
|
||||
'<?php unset($__componentOriginal'.$hash.'); ?>',
|
||||
'<?php endif; ?>',
|
||||
'<?php echo $__env->renderComponent(); ?>',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the end-component statements into valid PHP.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function compileEndComponentClass()
|
||||
{
|
||||
return static::compileEndComponent()."\n".implode("\n", [
|
||||
'<?php endif; ?>',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -66,4 +140,37 @@ trait CompilesComponents
|
||||
{
|
||||
return $this->compileEndComponent();
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the prop statement into valid PHP.
|
||||
*
|
||||
* @param string $expression
|
||||
* @return string
|
||||
*/
|
||||
protected function compileProps($expression)
|
||||
{
|
||||
return "<?php \$attributes = \$attributes->exceptProps{$expression}; ?>
|
||||
<?php foreach (array_filter({$expression}, 'is_string', ARRAY_FILTER_USE_KEY) as \$__key => \$__value) {
|
||||
\$\$__key = \$\$__key ?? \$__value;
|
||||
} ?>
|
||||
<?php \$__defined_vars = get_defined_vars(); ?>
|
||||
<?php foreach (\$attributes as \$__key => \$__value) {
|
||||
if (array_key_exists(\$__key, \$__defined_vars)) unset(\$\$__key);
|
||||
} ?>
|
||||
<?php unset(\$__defined_vars); ?>";
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanitize the given component attribute value.
|
||||
*
|
||||
* @param mixed $value
|
||||
* @return mixed
|
||||
*/
|
||||
public static function sanitizeComponentAttribute($value)
|
||||
{
|
||||
return is_string($value) ||
|
||||
(is_object($value) && method_exists($value, '__toString'))
|
||||
? e($value)
|
||||
: $value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
namespace Illuminate\View\Compilers\Concerns;
|
||||
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
trait CompilesConditionals
|
||||
{
|
||||
/**
|
||||
@@ -47,6 +49,47 @@ trait CompilesConditionals
|
||||
return '<?php endif; ?>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the env statements into valid PHP.
|
||||
*
|
||||
* @param string $environments
|
||||
* @return string
|
||||
*/
|
||||
protected function compileEnv($environments)
|
||||
{
|
||||
return "<?php if(app()->environment{$environments}): ?>";
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the end-env statements into valid PHP.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function compileEndEnv()
|
||||
{
|
||||
return '<?php endif; ?>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the production statements into valid PHP.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function compileProduction()
|
||||
{
|
||||
return "<?php if(app()->environment('production')): ?>";
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the end-production statements into valid PHP.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function compileEndProduction()
|
||||
{
|
||||
return '<?php endif; ?>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the if-guest statements into valid PHP.
|
||||
*
|
||||
@@ -94,6 +137,17 @@ trait CompilesConditionals
|
||||
return "<?php if (! empty(trim(\$__env->yieldContent{$expression}))): ?>";
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the section-missing statements into valid PHP.
|
||||
*
|
||||
* @param string $expression
|
||||
* @return string
|
||||
*/
|
||||
protected function compileSectionMissing($expression)
|
||||
{
|
||||
return "<?php if (empty(trim(\$__env->yieldContent{$expression}))): ?>";
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the if statements into valid PHP.
|
||||
*
|
||||
@@ -227,4 +281,26 @@ trait CompilesConditionals
|
||||
{
|
||||
return '<?php endswitch; ?>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile an once block into valid PHP.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function compileOnce($id = null)
|
||||
{
|
||||
$id = $id ? $this->stripParentheses($id) : "'".(string) Str::uuid()."'";
|
||||
|
||||
return '<?php if (! $__env->hasRenderedOnce('.$id.')): $__env->markAsRenderedOnce('.$id.'); ?>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile an end-once block into valid PHP.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function compileEndOnce()
|
||||
{
|
||||
return '<?php endif; ?>';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ trait CompilesEchos
|
||||
* @param string $value
|
||||
* @return string
|
||||
*/
|
||||
protected function compileEchos($value)
|
||||
public function compileEchos($value)
|
||||
{
|
||||
foreach ($this->getEchoMethods() as $method) {
|
||||
$value = $this->$method($value);
|
||||
|
||||
@@ -7,7 +7,7 @@ trait CompilesTranslations
|
||||
/**
|
||||
* Compile the lang statements into valid PHP.
|
||||
*
|
||||
* @param string $expression
|
||||
* @param string|null $expression
|
||||
* @return string
|
||||
*/
|
||||
protected function compileLang($expression)
|
||||
|
||||
279
vendor/laravel/framework/src/Illuminate/View/Component.php
vendored
Normal file
279
vendor/laravel/framework/src/Illuminate/View/Component.php
vendored
Normal file
@@ -0,0 +1,279 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\View;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Container\Container;
|
||||
use Illuminate\Support\Str;
|
||||
use ReflectionClass;
|
||||
use ReflectionMethod;
|
||||
use ReflectionProperty;
|
||||
|
||||
abstract class Component
|
||||
{
|
||||
/**
|
||||
* The cache of public property names, keyed by class.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected static $propertyCache = [];
|
||||
|
||||
/**
|
||||
* The cache of public method names, keyed by class.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected static $methodCache = [];
|
||||
|
||||
/**
|
||||
* The properties / methods that should not be exposed to the component.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $except = [];
|
||||
|
||||
/**
|
||||
* The component alias name.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $componentName;
|
||||
|
||||
/**
|
||||
* The component attributes.
|
||||
*
|
||||
* @var \Illuminate\View\ComponentAttributeBag
|
||||
*/
|
||||
public $attributes;
|
||||
|
||||
/**
|
||||
* Get the view / view contents that represent the component.
|
||||
*
|
||||
* @return \Illuminate\View\View|\Closure|string
|
||||
*/
|
||||
abstract public function render();
|
||||
|
||||
/**
|
||||
* Resolve the Blade view or view file that should be used when rendering the component.
|
||||
*
|
||||
* @return \Illuminate\View\View|\Closure|string
|
||||
*/
|
||||
public function resolveView()
|
||||
{
|
||||
$view = $this->render();
|
||||
|
||||
if ($view instanceof View) {
|
||||
return $view;
|
||||
}
|
||||
|
||||
$resolver = function ($view) {
|
||||
$factory = Container::getInstance()->make('view');
|
||||
|
||||
return $factory->exists($view)
|
||||
? $view
|
||||
: $this->createBladeViewFromString($factory, $view);
|
||||
};
|
||||
|
||||
return $view instanceof Closure ? function (array $data = []) use ($view, $resolver) {
|
||||
return $resolver($view($data));
|
||||
}
|
||||
: $resolver($view);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a Blade view with the raw component string content.
|
||||
*
|
||||
* @param \Illuminate\Contracts\View\Factory $factory
|
||||
* @param string $contents
|
||||
* @return string
|
||||
*/
|
||||
protected function createBladeViewFromString($factory, $contents)
|
||||
{
|
||||
$factory->addNamespace(
|
||||
'__components',
|
||||
$directory = Container::getInstance()['config']->get('view.compiled')
|
||||
);
|
||||
|
||||
if (! file_exists($viewFile = $directory.'/'.sha1($contents).'.blade.php')) {
|
||||
if (! is_dir($directory)) {
|
||||
mkdir($directory, 0755, true);
|
||||
}
|
||||
|
||||
file_put_contents($viewFile, $contents);
|
||||
}
|
||||
|
||||
return '__components::'.basename($viewFile, '.blade.php');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the data that should be supplied to the view.
|
||||
*
|
||||
* @author Freek Van der Herten
|
||||
* @author Brent Roose
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function data()
|
||||
{
|
||||
$this->attributes = $this->attributes ?: new ComponentAttributeBag;
|
||||
|
||||
return array_merge($this->extractPublicProperties(), $this->extractPublicMethods());
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract the public properties for the component.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function extractPublicProperties()
|
||||
{
|
||||
$class = get_class($this);
|
||||
|
||||
if (! isset(static::$propertyCache[$class])) {
|
||||
$reflection = new ReflectionClass($this);
|
||||
|
||||
static::$propertyCache[$class] = collect($reflection->getProperties(ReflectionProperty::IS_PUBLIC))
|
||||
->reject(function (ReflectionProperty $property) {
|
||||
return $property->isStatic();
|
||||
})
|
||||
->reject(function (ReflectionProperty $property) {
|
||||
return $this->shouldIgnore($property->getName());
|
||||
})
|
||||
->map(function (ReflectionProperty $property) {
|
||||
return $property->getName();
|
||||
})->all();
|
||||
}
|
||||
|
||||
$values = [];
|
||||
|
||||
foreach (static::$propertyCache[$class] as $property) {
|
||||
$values[$property] = $this->{$property};
|
||||
}
|
||||
|
||||
return $values;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract the public methods for the component.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function extractPublicMethods()
|
||||
{
|
||||
$class = get_class($this);
|
||||
|
||||
if (! isset(static::$methodCache[$class])) {
|
||||
$reflection = new ReflectionClass($this);
|
||||
|
||||
static::$methodCache[$class] = collect($reflection->getMethods(ReflectionMethod::IS_PUBLIC))
|
||||
->reject(function (ReflectionMethod $method) {
|
||||
return $this->shouldIgnore($method->getName());
|
||||
})
|
||||
->map(function (ReflectionMethod $method) {
|
||||
return $method->getName();
|
||||
});
|
||||
}
|
||||
|
||||
$values = [];
|
||||
|
||||
foreach (static::$methodCache[$class] as $method) {
|
||||
$values[$method] = $this->createVariableFromMethod(new ReflectionMethod($this, $method));
|
||||
}
|
||||
|
||||
return $values;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a callable variable from the given method.
|
||||
*
|
||||
* @param \ReflectionMethod $method
|
||||
* @return mixed
|
||||
*/
|
||||
protected function createVariableFromMethod(ReflectionMethod $method)
|
||||
{
|
||||
return $method->getNumberOfParameters() === 0
|
||||
? $this->createInvokableVariable($method->getName())
|
||||
: Closure::fromCallable([$this, $method->getName()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an invokable, toStringable variable for the given component method.
|
||||
*
|
||||
* @param string $method
|
||||
* @return \Illuminate\View\InvokableComponentVariable
|
||||
*/
|
||||
protected function createInvokableVariable(string $method)
|
||||
{
|
||||
return new InvokableComponentVariable(function () use ($method) {
|
||||
return $this->{$method}();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the given property / method should be ignored.
|
||||
*
|
||||
* @param string $name
|
||||
* @return bool
|
||||
*/
|
||||
protected function shouldIgnore($name)
|
||||
{
|
||||
return Str::startsWith($name, '__') ||
|
||||
in_array($name, $this->ignoredMethods());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the methods that should be ignored.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function ignoredMethods()
|
||||
{
|
||||
return array_merge([
|
||||
'data',
|
||||
'render',
|
||||
'resolveView',
|
||||
'shouldRender',
|
||||
'view',
|
||||
'withName',
|
||||
'withAttributes',
|
||||
], $this->except);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the component alias name.
|
||||
*
|
||||
* @param string $name
|
||||
* @return $this
|
||||
*/
|
||||
public function withName($name)
|
||||
{
|
||||
$this->componentName = $name;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the extra attributes that the component should make available.
|
||||
*
|
||||
* @param array $attributes
|
||||
* @return $this
|
||||
*/
|
||||
public function withAttributes(array $attributes)
|
||||
{
|
||||
$this->attributes = $this->attributes ?: new ComponentAttributeBag;
|
||||
|
||||
$this->attributes->setAttributes($attributes);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the component should be rendered.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function shouldRender()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
308
vendor/laravel/framework/src/Illuminate/View/ComponentAttributeBag.php
vendored
Normal file
308
vendor/laravel/framework/src/Illuminate/View/ComponentAttributeBag.php
vendored
Normal file
@@ -0,0 +1,308 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\View;
|
||||
|
||||
use ArrayAccess;
|
||||
use ArrayIterator;
|
||||
use Illuminate\Contracts\Support\Htmlable;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\HtmlString;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Support\Traits\Macroable;
|
||||
use IteratorAggregate;
|
||||
|
||||
class ComponentAttributeBag implements ArrayAccess, Htmlable, IteratorAggregate
|
||||
{
|
||||
use Macroable;
|
||||
|
||||
/**
|
||||
* The raw array of attributes.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $attributes = [];
|
||||
|
||||
/**
|
||||
* Create a new component attribute bag instance.
|
||||
*
|
||||
* @param array $attributes
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(array $attributes = [])
|
||||
{
|
||||
$this->attributes = $attributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the first attribute's value.
|
||||
*
|
||||
* @param mixed $default
|
||||
* @return mixed
|
||||
*/
|
||||
public function first($default = null)
|
||||
{
|
||||
return $this->getIterator()->current() ?? value($default);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a given attribute from the attribute array.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $default
|
||||
* @return mixed
|
||||
*/
|
||||
public function get($key, $default = null)
|
||||
{
|
||||
return $this->attributes[$key] ?? value($default);
|
||||
}
|
||||
|
||||
/**
|
||||
* Only include the given attribute from the attribute array.
|
||||
*
|
||||
* @param mixed|array $keys
|
||||
* @return static
|
||||
*/
|
||||
public function only($keys)
|
||||
{
|
||||
if (is_null($keys)) {
|
||||
$values = $this->attributes;
|
||||
} else {
|
||||
$keys = Arr::wrap($keys);
|
||||
|
||||
$values = Arr::only($this->attributes, $keys);
|
||||
}
|
||||
|
||||
return new static($values);
|
||||
}
|
||||
|
||||
/**
|
||||
* Exclude the given attribute from the attribute array.
|
||||
*
|
||||
* @param mixed|array $keys
|
||||
* @return static
|
||||
*/
|
||||
public function except($keys)
|
||||
{
|
||||
if (is_null($keys)) {
|
||||
$values = $this->attributes;
|
||||
} else {
|
||||
$keys = Arr::wrap($keys);
|
||||
|
||||
$values = Arr::except($this->attributes, $keys);
|
||||
}
|
||||
|
||||
return new static($values);
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter the attributes, returning a bag of attributes that pass the filter.
|
||||
*
|
||||
* @param callable $callback
|
||||
* @return static
|
||||
*/
|
||||
public function filter($callback)
|
||||
{
|
||||
return new static(collect($this->attributes)->filter($callback)->all());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a bag of attributes that have keys starting with the given value / pattern.
|
||||
*
|
||||
* @param string $string
|
||||
* @return static
|
||||
*/
|
||||
public function whereStartsWith($string)
|
||||
{
|
||||
return $this->filter(function ($value, $key) use ($string) {
|
||||
return Str::startsWith($key, $string);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a bag of attributes with keys that do not start with the given value / pattern.
|
||||
*
|
||||
* @param string $string
|
||||
* @return static
|
||||
*/
|
||||
public function whereDoesntStartWith($string)
|
||||
{
|
||||
return $this->filter(function ($value, $key) use ($string) {
|
||||
return ! Str::startsWith($key, $string);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a bag of attributes that have keys starting with the given value / pattern.
|
||||
*
|
||||
* @param string $string
|
||||
* @return static
|
||||
*/
|
||||
public function thatStartWith($string)
|
||||
{
|
||||
return $this->whereStartsWith($string);
|
||||
}
|
||||
|
||||
/**
|
||||
* Exclude the given attribute from the attribute array.
|
||||
*
|
||||
* @param mixed|array $keys
|
||||
* @return static
|
||||
*/
|
||||
public function exceptProps($keys)
|
||||
{
|
||||
$props = [];
|
||||
|
||||
foreach ($keys as $key => $defaultValue) {
|
||||
$key = is_numeric($key) ? $defaultValue : $key;
|
||||
|
||||
$props[] = $key;
|
||||
$props[] = Str::kebab($key);
|
||||
}
|
||||
|
||||
return $this->except($props);
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge additional attributes / values into the attribute bag.
|
||||
*
|
||||
* @param array $attributeDefaults
|
||||
* @return static
|
||||
*/
|
||||
public function merge(array $attributeDefaults = [])
|
||||
{
|
||||
$attributes = [];
|
||||
|
||||
$attributeDefaults = array_map(function ($value) {
|
||||
if (is_null($value) || is_bool($value)) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
return e($value);
|
||||
}, $attributeDefaults);
|
||||
|
||||
foreach ($this->attributes as $key => $value) {
|
||||
if ($key !== 'class') {
|
||||
$attributes[$key] = $value;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
$attributes[$key] = implode(' ', array_unique(
|
||||
array_filter([$attributeDefaults[$key] ?? '', $value])
|
||||
));
|
||||
}
|
||||
|
||||
return new static(array_merge($attributeDefaults, $attributes));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the underlying attributes.
|
||||
*
|
||||
* @param array $attributes
|
||||
* @return void
|
||||
*/
|
||||
public function setAttributes(array $attributes)
|
||||
{
|
||||
$this->attributes = $attributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get content as a string of HTML.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function toHtml()
|
||||
{
|
||||
return (string) $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge additional attributes / values into the attribute bag.
|
||||
*
|
||||
* @param array $attributeDefaults
|
||||
* @return \Illuminate\Support\HtmlString
|
||||
*/
|
||||
public function __invoke(array $attributeDefaults = [])
|
||||
{
|
||||
return new HtmlString((string) $this->merge($attributeDefaults));
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the given offset exists.
|
||||
*
|
||||
* @param string $offset
|
||||
* @return bool
|
||||
*/
|
||||
public function offsetExists($offset)
|
||||
{
|
||||
return isset($this->attributes[$offset]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value at the given offset.
|
||||
*
|
||||
* @param string $offset
|
||||
* @return mixed
|
||||
*/
|
||||
public function offsetGet($offset)
|
||||
{
|
||||
return $this->get($offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value at a given offset.
|
||||
*
|
||||
* @param string $offset
|
||||
* @param mixed $value
|
||||
* @return void
|
||||
*/
|
||||
public function offsetSet($offset, $value)
|
||||
{
|
||||
$this->attributes[$offset] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the value at the given offset.
|
||||
*
|
||||
* @param string $offset
|
||||
* @return void
|
||||
*/
|
||||
public function offsetUnset($offset)
|
||||
{
|
||||
unset($this->attributes[$offset]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an iterator for the items.
|
||||
*
|
||||
* @return \ArrayIterator
|
||||
*/
|
||||
public function getIterator()
|
||||
{
|
||||
return new ArrayIterator($this->attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implode the attributes into a single HTML ready string.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
$string = '';
|
||||
|
||||
foreach ($this->attributes as $key => $value) {
|
||||
if ($value === false || is_null($value)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($value === true) {
|
||||
$value = $key;
|
||||
}
|
||||
|
||||
$string .= ' '.$key.'="'.str_replace('"', '\\"', trim($value)).'"';
|
||||
}
|
||||
|
||||
return trim($string);
|
||||
}
|
||||
}
|
||||
@@ -2,8 +2,10 @@
|
||||
|
||||
namespace Illuminate\View\Concerns;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\HtmlString;
|
||||
use Illuminate\View\View;
|
||||
use InvalidArgumentException;
|
||||
|
||||
trait ManagesComponents
|
||||
@@ -39,14 +41,14 @@ trait ManagesComponents
|
||||
/**
|
||||
* Start a component rendering process.
|
||||
*
|
||||
* @param string $name
|
||||
* @param \Illuminate\View\View|\Closure|string $view
|
||||
* @param array $data
|
||||
* @return void
|
||||
*/
|
||||
public function startComponent($name, array $data = [])
|
||||
public function startComponent($view, array $data = [])
|
||||
{
|
||||
if (ob_start()) {
|
||||
$this->componentStack[] = $name;
|
||||
$this->componentStack[] = $view;
|
||||
|
||||
$this->componentData[$this->currentComponent()] = $data;
|
||||
|
||||
@@ -77,18 +79,27 @@ trait ManagesComponents
|
||||
*/
|
||||
public function renderComponent()
|
||||
{
|
||||
$name = array_pop($this->componentStack);
|
||||
$view = array_pop($this->componentStack);
|
||||
|
||||
return $this->make($name, $this->componentData($name))->render();
|
||||
$data = $this->componentData();
|
||||
|
||||
if ($view instanceof Closure) {
|
||||
$view = $view($data);
|
||||
}
|
||||
|
||||
if ($view instanceof View) {
|
||||
return $view->with($data)->render();
|
||||
} else {
|
||||
return $this->make($view, $data)->render();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the data for the given component.
|
||||
*
|
||||
* @param string $name
|
||||
* @return array
|
||||
*/
|
||||
protected function componentData($name)
|
||||
protected function componentData()
|
||||
{
|
||||
return array_merge(
|
||||
$this->componentData[count($this->componentStack)],
|
||||
|
||||
@@ -209,6 +209,17 @@ trait ManagesLayouts
|
||||
return array_key_exists($name, $this->sections);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if section does not exist.
|
||||
*
|
||||
* @param string $name
|
||||
* @return bool
|
||||
*/
|
||||
public function sectionMissing($name)
|
||||
{
|
||||
return ! $this->hasSection($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the contents of a section.
|
||||
*
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
|
||||
namespace Illuminate\View\Engines;
|
||||
|
||||
use Exception;
|
||||
use Illuminate\View\Compilers\CompilerInterface;
|
||||
use Illuminate\View\ViewException;
|
||||
use Throwable;
|
||||
|
||||
class CompilerEngine extends PhpEngine
|
||||
{
|
||||
@@ -51,12 +51,10 @@ class CompilerEngine extends PhpEngine
|
||||
$this->compiler->compile($path);
|
||||
}
|
||||
|
||||
$compiled = $this->compiler->getCompiledPath($path);
|
||||
|
||||
// Once we have the path to the compiled file, we will evaluate the paths with
|
||||
// typical PHP just like any other templates. We also keep a stack of views
|
||||
// which have been rendered for right exception messages to be generated.
|
||||
$results = $this->evaluatePath($compiled, $data);
|
||||
$results = $this->evaluatePath($this->compiler->getCompiledPath($path), $data);
|
||||
|
||||
array_pop($this->lastCompiled);
|
||||
|
||||
@@ -66,13 +64,13 @@ class CompilerEngine extends PhpEngine
|
||||
/**
|
||||
* Handle a view exception.
|
||||
*
|
||||
* @param \Exception $e
|
||||
* @param \Throwable $e
|
||||
* @param int $obLevel
|
||||
* @return void
|
||||
*
|
||||
* @throws \Exception
|
||||
* @throws \Throwable
|
||||
*/
|
||||
protected function handleViewException(Exception $e, $obLevel)
|
||||
protected function handleViewException(Throwable $e, $obLevel)
|
||||
{
|
||||
$e = new ViewException($this->getMessage($e), 0, 1, $e->getFile(), $e->getLine(), $e);
|
||||
|
||||
@@ -82,10 +80,10 @@ class CompilerEngine extends PhpEngine
|
||||
/**
|
||||
* Get the exception message for an exception.
|
||||
*
|
||||
* @param \Exception $e
|
||||
* @param \Throwable $e
|
||||
* @return string
|
||||
*/
|
||||
protected function getMessage(Exception $e)
|
||||
protected function getMessage(Throwable $e)
|
||||
{
|
||||
return $e->getMessage().' (View: '.realpath(last($this->lastCompiled)).')';
|
||||
}
|
||||
|
||||
@@ -2,9 +2,7 @@
|
||||
|
||||
namespace Illuminate\View\Engines;
|
||||
|
||||
use Exception;
|
||||
use Illuminate\Contracts\View\Engine;
|
||||
use Symfony\Component\Debug\Exception\FatalThrowableError;
|
||||
use Throwable;
|
||||
|
||||
class PhpEngine implements Engine
|
||||
@@ -41,10 +39,8 @@ class PhpEngine implements Engine
|
||||
// an exception is thrown. This prevents any partial views from leaking.
|
||||
try {
|
||||
include $__path;
|
||||
} catch (Exception $e) {
|
||||
$this->handleViewException($e, $obLevel);
|
||||
} catch (Throwable $e) {
|
||||
$this->handleViewException(new FatalThrowableError($e), $obLevel);
|
||||
$this->handleViewException($e, $obLevel);
|
||||
}
|
||||
|
||||
return ltrim(ob_get_clean());
|
||||
@@ -53,13 +49,13 @@ class PhpEngine implements Engine
|
||||
/**
|
||||
* Handle a view exception.
|
||||
*
|
||||
* @param \Exception $e
|
||||
* @param \Throwable $e
|
||||
* @param int $obLevel
|
||||
* @return void
|
||||
*
|
||||
* @throws \Exception
|
||||
* @throws \Throwable
|
||||
*/
|
||||
protected function handleViewException(Exception $e, $obLevel)
|
||||
protected function handleViewException(Throwable $e, $obLevel)
|
||||
{
|
||||
while (ob_get_level() > $obLevel) {
|
||||
ob_end_clean();
|
||||
|
||||
@@ -83,6 +83,13 @@ class Factory implements FactoryContract
|
||||
*/
|
||||
protected $renderCount = 0;
|
||||
|
||||
/**
|
||||
* The "once" block IDs that have been rendered.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $renderedOnce = [];
|
||||
|
||||
/**
|
||||
* Create a new view factory instance.
|
||||
*
|
||||
@@ -281,7 +288,7 @@ class Factory implements FactoryContract
|
||||
public function getEngineFromPath($path)
|
||||
{
|
||||
if (! $extension = $this->getExtension($path)) {
|
||||
throw new InvalidArgumentException("Unrecognized extension in file: {$path}");
|
||||
throw new InvalidArgumentException("Unrecognized extension in file: {$path}.");
|
||||
}
|
||||
|
||||
$engine = $this->extensions[$extension];
|
||||
@@ -293,7 +300,7 @@ class Factory implements FactoryContract
|
||||
* Get the extension used by the view file.
|
||||
*
|
||||
* @param string $path
|
||||
* @return string
|
||||
* @return string|null
|
||||
*/
|
||||
protected function getExtension($path)
|
||||
{
|
||||
@@ -352,6 +359,28 @@ class Factory implements FactoryContract
|
||||
return $this->renderCount == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the given once token has been rendered.
|
||||
*
|
||||
* @param string $id
|
||||
* @return bool
|
||||
*/
|
||||
public function hasRenderedOnce(string $id)
|
||||
{
|
||||
return isset($this->renderedOnce[$id]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark the given once token as having been rendered.
|
||||
*
|
||||
* @param string $id
|
||||
* @return void
|
||||
*/
|
||||
public function markAsRenderedOnce(string $id)
|
||||
{
|
||||
$this->renderedOnce[$id] = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a location to the array of view locations.
|
||||
*
|
||||
@@ -434,6 +463,7 @@ class Factory implements FactoryContract
|
||||
public function flushState()
|
||||
{
|
||||
$this->renderCount = 0;
|
||||
$this->renderedOnce = [];
|
||||
|
||||
$this->flushSections();
|
||||
$this->flushStacks();
|
||||
|
||||
95
vendor/laravel/framework/src/Illuminate/View/InvokableComponentVariable.php
vendored
Normal file
95
vendor/laravel/framework/src/Illuminate/View/InvokableComponentVariable.php
vendored
Normal file
@@ -0,0 +1,95 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\View;
|
||||
|
||||
use ArrayIterator;
|
||||
use Closure;
|
||||
use Illuminate\Contracts\Support\DeferringDisplayableValue;
|
||||
use Illuminate\Support\Enumerable;
|
||||
use IteratorAggregate;
|
||||
|
||||
class InvokableComponentVariable implements DeferringDisplayableValue, IteratorAggregate
|
||||
{
|
||||
/**
|
||||
* The callable instance to resolve the variable value.
|
||||
*
|
||||
* @var \Closure
|
||||
*/
|
||||
protected $callable;
|
||||
|
||||
/**
|
||||
* Create a new variable instance.
|
||||
*
|
||||
* @param \Closure $callable
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Closure $callable)
|
||||
{
|
||||
$this->callable = $callable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve the displayable value that the class is deferring.
|
||||
*
|
||||
* @return \Illuminate\Contracts\Support\Htmlable|string
|
||||
*/
|
||||
public function resolveDisplayableValue()
|
||||
{
|
||||
return $this->__invoke();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an interator instance for the variable.
|
||||
*
|
||||
* @return \ArrayIterator
|
||||
*/
|
||||
public function getIterator()
|
||||
{
|
||||
$result = $this->__invoke();
|
||||
|
||||
return new ArrayIterator($result instanceof Enumerable ? $result->all() : $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Dynamically proxy attribute access to the variable.
|
||||
*
|
||||
* @param string $key
|
||||
* @return mixed
|
||||
*/
|
||||
public function __get($key)
|
||||
{
|
||||
return $this->__invoke()->{$key};
|
||||
}
|
||||
|
||||
/**
|
||||
* Dynamically proxy method access to the variable.
|
||||
*
|
||||
* @param string $method
|
||||
* @param array $parameters
|
||||
* @return mixed
|
||||
*/
|
||||
public function __call($method, $parameters)
|
||||
{
|
||||
return $this->__invoke()->{$method}(...$parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve the variable.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function __invoke()
|
||||
{
|
||||
return call_user_func($this->callable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve the variable as a string.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return (string) $this->__invoke();
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,6 @@ namespace Illuminate\View;
|
||||
|
||||
use ArrayAccess;
|
||||
use BadMethodCallException;
|
||||
use Exception;
|
||||
use Illuminate\Contracts\Support\Arrayable;
|
||||
use Illuminate\Contracts\Support\Htmlable;
|
||||
use Illuminate\Contracts\Support\MessageProvider;
|
||||
@@ -14,6 +13,7 @@ use Illuminate\Contracts\View\View as ViewContract;
|
||||
use Illuminate\Support\MessageBag;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Support\Traits\Macroable;
|
||||
use Illuminate\Support\ViewErrorBag;
|
||||
use Throwable;
|
||||
|
||||
class View implements ArrayAccess, Htmlable, ViewContract
|
||||
@@ -98,10 +98,6 @@ class View implements ArrayAccess, Htmlable, ViewContract
|
||||
$this->factory->flushStateIfDoneRendering();
|
||||
|
||||
return ! is_null($response) ? $response : $contents;
|
||||
} catch (Exception $e) {
|
||||
$this->factory->flushState();
|
||||
|
||||
throw $e;
|
||||
} catch (Throwable $e) {
|
||||
$this->factory->flushState();
|
||||
|
||||
@@ -210,25 +206,27 @@ class View implements ArrayAccess, Htmlable, ViewContract
|
||||
* Add validation errors to the view.
|
||||
*
|
||||
* @param \Illuminate\Contracts\Support\MessageProvider|array $provider
|
||||
* @param string $bag
|
||||
* @return $this
|
||||
*/
|
||||
public function withErrors($provider)
|
||||
public function withErrors($provider, $bag = 'default')
|
||||
{
|
||||
$this->with('errors', $this->formatErrors($provider));
|
||||
|
||||
return $this;
|
||||
return $this->with('errors', (new ViewErrorBag)->put(
|
||||
$bag, $this->formatErrors($provider)
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Format the given message provider into a MessageBag.
|
||||
* Parse the given errors into an appropriate value.
|
||||
*
|
||||
* @param \Illuminate\Contracts\Support\MessageProvider|array $provider
|
||||
* @param \Illuminate\Contracts\Support\MessageProvider|array|string $provider
|
||||
* @return \Illuminate\Support\MessageBag
|
||||
*/
|
||||
protected function formatErrors($provider)
|
||||
{
|
||||
return $provider instanceof MessageProvider
|
||||
? $provider->getMessageBag() : new MessageBag((array) $provider);
|
||||
? $provider->getMessageBag()
|
||||
: new MessageBag((array) $provider);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -5,7 +5,7 @@ namespace Illuminate\View;
|
||||
class ViewName
|
||||
{
|
||||
/**
|
||||
* Normalize the given event name.
|
||||
* Normalize the given view name.
|
||||
*
|
||||
* @param string $name
|
||||
* @return string
|
||||
|
||||
@@ -87,10 +87,8 @@ class ViewServiceProvider extends ServiceProvider
|
||||
*/
|
||||
public function registerBladeCompiler()
|
||||
{
|
||||
$this->app->singleton('blade.compiler', function () {
|
||||
return new BladeCompiler(
|
||||
$this->app['files'], $this->app['config']['view.compiled']
|
||||
);
|
||||
$this->app->singleton('blade.compiler', function ($app) {
|
||||
return new BladeCompiler($app['files'], $app['config']['view.compiled']);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -16,12 +16,11 @@
|
||||
"require": {
|
||||
"php": "^7.2.5|^8.0",
|
||||
"ext-json": "*",
|
||||
"illuminate/container": "^6.0",
|
||||
"illuminate/contracts": "^6.0",
|
||||
"illuminate/events": "^6.0",
|
||||
"illuminate/filesystem": "^6.0",
|
||||
"illuminate/support": "^6.0",
|
||||
"symfony/debug": "^4.3.4"
|
||||
"illuminate/container": "^7.0",
|
||||
"illuminate/contracts": "^7.0",
|
||||
"illuminate/events": "^7.0",
|
||||
"illuminate/filesystem": "^7.0",
|
||||
"illuminate/support": "^7.0"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
@@ -30,7 +29,7 @@
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "6.x-dev"
|
||||
"dev-master": "7.x-dev"
|
||||
}
|
||||
},
|
||||
"config": {
|
||||
|
||||
Reference in New Issue
Block a user