Upgrade framework
This commit is contained in:
60
vendor/laravel/framework/src/Illuminate/View/AnonymousComponent.php
vendored
Normal file
60
vendor/laravel/framework/src/Illuminate/View/AnonymousComponent.php
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
<?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 ?: $this->newAttributeBag();
|
||||
|
||||
return array_merge(
|
||||
($this->data['attributes'] ?? null)?->getAttributes() ?: [],
|
||||
$this->attributes->getAttributes(),
|
||||
$this->data,
|
||||
['attributes' => $this->attributes]
|
||||
);
|
||||
}
|
||||
}
|
||||
34
vendor/laravel/framework/src/Illuminate/View/AppendableAttributeValue.php
vendored
Normal file
34
vendor/laravel/framework/src/Illuminate/View/AppendableAttributeValue.php
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\View;
|
||||
|
||||
class AppendableAttributeValue
|
||||
{
|
||||
/**
|
||||
* The attribute value.
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
public $value;
|
||||
|
||||
/**
|
||||
* Create a new appendable attribute value.
|
||||
*
|
||||
* @param mixed $value
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($value)
|
||||
{
|
||||
$this->value = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the string value.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return (string) $this->value;
|
||||
}
|
||||
}
|
||||
@@ -2,23 +2,37 @@
|
||||
|
||||
namespace Illuminate\View\Compilers;
|
||||
|
||||
use Illuminate\Container\Container;
|
||||
use Illuminate\Contracts\Support\Htmlable;
|
||||
use Illuminate\Contracts\View\Factory as ViewFactory;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Support\Traits\ReflectsClosures;
|
||||
use Illuminate\View\Component;
|
||||
use InvalidArgumentException;
|
||||
|
||||
class BladeCompiler extends Compiler implements CompilerInterface
|
||||
{
|
||||
use Concerns\CompilesAuthorizations,
|
||||
Concerns\CompilesClasses,
|
||||
Concerns\CompilesComments,
|
||||
Concerns\CompilesComponents,
|
||||
Concerns\CompilesConditionals,
|
||||
Concerns\CompilesEchos,
|
||||
Concerns\CompilesErrors,
|
||||
Concerns\CompilesFragments,
|
||||
Concerns\CompilesHelpers,
|
||||
Concerns\CompilesIncludes,
|
||||
Concerns\CompilesInjections,
|
||||
Concerns\CompilesJson,
|
||||
Concerns\CompilesJs,
|
||||
Concerns\CompilesLayouts,
|
||||
Concerns\CompilesLoops,
|
||||
Concerns\CompilesRawPhp,
|
||||
Concerns\CompilesStacks,
|
||||
Concerns\CompilesTranslations;
|
||||
Concerns\CompilesTranslations,
|
||||
ReflectsClosures;
|
||||
|
||||
/**
|
||||
* All of the registered extensions.
|
||||
@@ -30,12 +44,24 @@ class BladeCompiler extends Compiler implements CompilerInterface
|
||||
/**
|
||||
* All custom "directive" handlers.
|
||||
*
|
||||
* This was implemented as a more usable "extend" in 5.1.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $customDirectives = [];
|
||||
|
||||
/**
|
||||
* All custom "condition" handlers.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $conditions = [];
|
||||
|
||||
/**
|
||||
* All of the registered precompilers.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $precompilers = [];
|
||||
|
||||
/**
|
||||
* The file currently being compiled.
|
||||
*
|
||||
@@ -46,10 +72,10 @@ class BladeCompiler extends Compiler implements CompilerInterface
|
||||
/**
|
||||
* All of the available compiler functions.
|
||||
*
|
||||
* @var array
|
||||
* @var string[]
|
||||
*/
|
||||
protected $compilers = [
|
||||
'Comments',
|
||||
// 'Comments',
|
||||
'Extensions',
|
||||
'Statements',
|
||||
'Echos',
|
||||
@@ -58,21 +84,21 @@ class BladeCompiler extends Compiler implements CompilerInterface
|
||||
/**
|
||||
* Array of opening and closing tags for raw echos.
|
||||
*
|
||||
* @var array
|
||||
* @var string[]
|
||||
*/
|
||||
protected $rawTags = ['{!!', '!!}'];
|
||||
|
||||
/**
|
||||
* Array of opening and closing tags for regular echos.
|
||||
*
|
||||
* @var array
|
||||
* @var string[]
|
||||
*/
|
||||
protected $contentTags = ['{{', '}}'];
|
||||
|
||||
/**
|
||||
* Array of opening and closing tags for escaped echos.
|
||||
*
|
||||
* @var array
|
||||
* @var string[]
|
||||
*/
|
||||
protected $escapedTags = ['{{{', '}}}'];
|
||||
|
||||
@@ -84,30 +110,58 @@ class BladeCompiler extends Compiler implements CompilerInterface
|
||||
protected $echoFormat = 'e(%s)';
|
||||
|
||||
/**
|
||||
* Array of footer lines to be added to template.
|
||||
* Array of footer lines to be added to the template.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $footer = [];
|
||||
|
||||
/**
|
||||
* Placeholder to temporary mark the position of verbatim blocks.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $verbatimPlaceholder = '@__verbatim__@';
|
||||
|
||||
/**
|
||||
* Array to temporary store the verbatim blocks found in the template.
|
||||
* Array to temporarily store the raw blocks found in the template.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $verbatimBlocks = [];
|
||||
protected $rawBlocks = [];
|
||||
|
||||
/**
|
||||
* The array of anonymous component paths to search for components in.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $anonymousComponentPaths = [];
|
||||
|
||||
/**
|
||||
* The array of anonymous component namespaces to autoload from.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $anonymousComponentNamespaces = [];
|
||||
|
||||
/**
|
||||
* The array of class component aliases and their class names.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $classComponentAliases = [];
|
||||
|
||||
/**
|
||||
* The array of class component namespaces to autoload from.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $classComponentNamespaces = [];
|
||||
|
||||
/**
|
||||
* Indicates if component tags should be compiled.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $compilesComponentTags = true;
|
||||
|
||||
/**
|
||||
* Compile the view at the given path.
|
||||
*
|
||||
* @param string $path
|
||||
* @param string|null $path
|
||||
* @return void
|
||||
*/
|
||||
public function compile($path = null)
|
||||
@@ -119,10 +173,50 @@ class BladeCompiler extends Compiler implements CompilerInterface
|
||||
if (! is_null($this->cachePath)) {
|
||||
$contents = $this->compileString($this->files->get($this->getPath()));
|
||||
|
||||
$this->files->put($this->getCompiledPath($this->getPath()), $contents);
|
||||
if (! empty($this->getPath())) {
|
||||
$contents = $this->appendFilePath($contents);
|
||||
}
|
||||
|
||||
$this->ensureCompiledDirectoryExists(
|
||||
$compiledPath = $this->getCompiledPath($this->getPath())
|
||||
);
|
||||
|
||||
$this->files->put($compiledPath, $contents);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Append the file path to the compiled string.
|
||||
*
|
||||
* @param string $contents
|
||||
* @return string
|
||||
*/
|
||||
protected function appendFilePath($contents)
|
||||
{
|
||||
$tokens = $this->getOpenAndClosingPhpTokens($contents);
|
||||
|
||||
if ($tokens->isNotEmpty() && $tokens->last() !== T_CLOSE_TAG) {
|
||||
$contents .= ' ?>';
|
||||
}
|
||||
|
||||
return $contents."<?php /**PATH {$this->getPath()} ENDPATH**/ ?>";
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the open and closing PHP tag tokens from the given string.
|
||||
*
|
||||
* @param string $contents
|
||||
* @return \Illuminate\Support\Collection
|
||||
*/
|
||||
protected function getOpenAndClosingPhpTokens($contents)
|
||||
{
|
||||
return collect(token_get_all($contents))
|
||||
->pluck(0)
|
||||
->filter(function ($token) {
|
||||
return in_array($token, [T_OPEN_TAG, T_OPEN_TAG_WITH_ECHO, T_CLOSE_TAG]);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the path currently being compiled.
|
||||
*
|
||||
@@ -152,14 +246,19 @@ class BladeCompiler extends Compiler implements CompilerInterface
|
||||
*/
|
||||
public function compileString($value)
|
||||
{
|
||||
$result = '';
|
||||
[$this->footer, $result] = [[], ''];
|
||||
|
||||
if (strpos($value, '@verbatim') !== false) {
|
||||
$value = $this->storeVerbatimBlocks($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 = $precompiler($value);
|
||||
}
|
||||
|
||||
$this->footer = [];
|
||||
|
||||
// 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
|
||||
// template as the correctly rendered PHP that can be rendered natively.
|
||||
@@ -167,8 +266,8 @@ class BladeCompiler extends Compiler implements CompilerInterface
|
||||
$result .= is_array($token) ? $this->parseToken($token) : $token;
|
||||
}
|
||||
|
||||
if (! empty($this->verbatimBlocks)) {
|
||||
$result = $this->restoreVerbatimBlocks($result);
|
||||
if (! empty($this->rawBlocks)) {
|
||||
$result = $this->restoreRawContent($result);
|
||||
}
|
||||
|
||||
// If there are any footer lines that need to get added to a template we will
|
||||
@@ -178,7 +277,93 @@ class BladeCompiler extends Compiler implements CompilerInterface
|
||||
$result = $this->addFooters($result);
|
||||
}
|
||||
|
||||
return $result;
|
||||
if (! empty($this->echoHandlers)) {
|
||||
$result = $this->addBladeCompilerVariable($result);
|
||||
}
|
||||
|
||||
return str_replace(
|
||||
['##BEGIN-COMPONENT-CLASS##', '##END-COMPONENT-CLASS##'],
|
||||
'',
|
||||
$result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluate and render a Blade string to HTML.
|
||||
*
|
||||
* @param string $string
|
||||
* @param array $data
|
||||
* @param bool $deleteCachedView
|
||||
* @return string
|
||||
*/
|
||||
public static function render($string, $data = [], $deleteCachedView = false)
|
||||
{
|
||||
$component = new class($string) extends Component
|
||||
{
|
||||
protected $template;
|
||||
|
||||
public function __construct($template)
|
||||
{
|
||||
$this->template = $template;
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return $this->template;
|
||||
}
|
||||
};
|
||||
|
||||
$view = Container::getInstance()
|
||||
->make(ViewFactory::class)
|
||||
->make($component->resolveView(), $data);
|
||||
|
||||
return tap($view->render(), function () use ($view, $deleteCachedView) {
|
||||
if ($deleteCachedView) {
|
||||
unlink($view->getPath());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Render a component instance to HTML.
|
||||
*
|
||||
* @param \Illuminate\View\Component $component
|
||||
* @return string
|
||||
*/
|
||||
public static function renderComponent(Component $component)
|
||||
{
|
||||
$data = $component->data();
|
||||
|
||||
$view = value($component->resolveView(), $data);
|
||||
|
||||
if ($view instanceof View) {
|
||||
return $view->with($data)->render();
|
||||
} elseif ($view instanceof Htmlable) {
|
||||
return $view->toHtml();
|
||||
} else {
|
||||
return Container::getInstance()
|
||||
->make(ViewFactory::class)
|
||||
->make($view, $data)
|
||||
->render();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Store the blocks that do not receive compilation.
|
||||
*
|
||||
* @param string $value
|
||||
* @return string
|
||||
*/
|
||||
protected function storeUncompiledBlocks($value)
|
||||
{
|
||||
if (str_contains($value, '@verbatim')) {
|
||||
$value = $this->storeVerbatimBlocks($value);
|
||||
}
|
||||
|
||||
if (str_contains($value, '@php')) {
|
||||
$value = $this->storePhpBlocks($value);
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -190,29 +375,81 @@ class BladeCompiler extends Compiler implements CompilerInterface
|
||||
protected function storeVerbatimBlocks($value)
|
||||
{
|
||||
return preg_replace_callback('/(?<!@)@verbatim(.*?)@endverbatim/s', function ($matches) {
|
||||
$this->verbatimBlocks[] = $matches[1];
|
||||
|
||||
return $this->verbatimPlaceholder;
|
||||
return $this->storeRawBlock($matches[1]);
|
||||
}, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Store the PHP blocks and replace them with a temporary placeholder.
|
||||
*
|
||||
* @param string $value
|
||||
* @return string
|
||||
*/
|
||||
protected function storePhpBlocks($value)
|
||||
{
|
||||
return preg_replace_callback('/(?<!@)@php(.*?)@endphp/s', function ($matches) {
|
||||
return $this->storeRawBlock("<?php{$matches[1]}?>");
|
||||
}, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a raw block and return a unique raw placeholder.
|
||||
*
|
||||
* @param string $value
|
||||
* @return string
|
||||
*/
|
||||
protected function storeRawBlock($value)
|
||||
{
|
||||
return $this->getRawPlaceholder(
|
||||
array_push($this->rawBlocks, $value) - 1
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the component tags.
|
||||
*
|
||||
* @param string $value
|
||||
* @return string
|
||||
*/
|
||||
protected function compileComponentTags($value)
|
||||
{
|
||||
if (! $this->compilesComponentTags) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
return (new ComponentTagCompiler(
|
||||
$this->classComponentAliases, $this->classComponentNamespaces, $this
|
||||
))->compile($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace the raw placeholders with the original code stored in the raw blocks.
|
||||
*
|
||||
* @param string $result
|
||||
* @return string
|
||||
*/
|
||||
protected function restoreVerbatimBlocks($result)
|
||||
protected function restoreRawContent($result)
|
||||
{
|
||||
$result = preg_replace_callback('/'.preg_quote($this->verbatimPlaceholder).'/', function () {
|
||||
return array_shift($this->verbatimBlocks);
|
||||
$result = preg_replace_callback('/'.$this->getRawPlaceholder('(\d+)').'/', function ($matches) {
|
||||
return $this->rawBlocks[$matches[1]];
|
||||
}, $result);
|
||||
|
||||
$this->verbatimBlocks = [];
|
||||
$this->rawBlocks = [];
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a placeholder to temporarily mark the position of raw blocks.
|
||||
*
|
||||
* @param int|string $replace
|
||||
* @return string
|
||||
*/
|
||||
protected function getRawPlaceholder($replace)
|
||||
{
|
||||
return str_replace('#', $replace, '@__raw_block_#__@');
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the stored footers onto the given content.
|
||||
*
|
||||
@@ -221,8 +458,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));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -233,7 +470,7 @@ class BladeCompiler extends Compiler implements CompilerInterface
|
||||
*/
|
||||
protected function parseToken($token)
|
||||
{
|
||||
list($id, $content) = $token;
|
||||
[$id, $content] = $token;
|
||||
|
||||
if ($id == T_INLINE_HTML) {
|
||||
foreach ($this->compilers as $type) {
|
||||
@@ -253,7 +490,7 @@ class BladeCompiler extends Compiler implements CompilerInterface
|
||||
protected function compileExtensions($value)
|
||||
{
|
||||
foreach ($this->extensions as $compiler) {
|
||||
$value = call_user_func($compiler, $value, $this);
|
||||
$value = $compiler($value, $this);
|
||||
}
|
||||
|
||||
return $value;
|
||||
@@ -282,12 +519,14 @@ class BladeCompiler extends Compiler implements CompilerInterface
|
||||
*/
|
||||
protected function compileStatement($match)
|
||||
{
|
||||
if (Str::contains($match[1], '@')) {
|
||||
if (str_contains($match[1], '@')) {
|
||||
$match[0] = isset($match[3]) ? $match[1].$match[3] : $match[1];
|
||||
} elseif (isset($this->customDirectives[$match[1]])) {
|
||||
$match[0] = $this->callCustomDirective($match[1], Arr::get($match, 3));
|
||||
} elseif (method_exists($this, $method = 'compile'.ucfirst($match[1]))) {
|
||||
$match[0] = $this->$method(Arr::get($match, 3));
|
||||
} else {
|
||||
return $match[0];
|
||||
}
|
||||
|
||||
return isset($match[3]) ? $match[0] : $match[0].$match[2];
|
||||
@@ -302,7 +541,9 @@ class BladeCompiler extends Compiler implements CompilerInterface
|
||||
*/
|
||||
protected function callCustomDirective($name, $value)
|
||||
{
|
||||
if (Str::startsWith($value, '(') && Str::endsWith($value, ')')) {
|
||||
$value ??= '';
|
||||
|
||||
if (str_starts_with($value, '(') && str_ends_with($value, ')')) {
|
||||
$value = Str::substr($value, 1, -1);
|
||||
}
|
||||
|
||||
@@ -345,15 +586,257 @@ class BladeCompiler extends Compiler implements CompilerInterface
|
||||
return $this->extensions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register an "if" statement directive.
|
||||
*
|
||||
* @param string $name
|
||||
* @param callable $callback
|
||||
* @return void
|
||||
*/
|
||||
public function if($name, callable $callback)
|
||||
{
|
||||
$this->conditions[$name] = $callback;
|
||||
|
||||
$this->directive($name, function ($expression) use ($name) {
|
||||
return $expression !== ''
|
||||
? "<?php if (\Illuminate\Support\Facades\Blade::check('{$name}', {$expression})): ?>"
|
||||
: "<?php if (\Illuminate\Support\Facades\Blade::check('{$name}')): ?>";
|
||||
});
|
||||
|
||||
$this->directive('unless'.$name, function ($expression) use ($name) {
|
||||
return $expression !== ''
|
||||
? "<?php if (! \Illuminate\Support\Facades\Blade::check('{$name}', {$expression})): ?>"
|
||||
: "<?php if (! \Illuminate\Support\Facades\Blade::check('{$name}')): ?>";
|
||||
});
|
||||
|
||||
$this->directive('else'.$name, function ($expression) use ($name) {
|
||||
return $expression !== ''
|
||||
? "<?php elseif (\Illuminate\Support\Facades\Blade::check('{$name}', {$expression})): ?>"
|
||||
: "<?php elseif (\Illuminate\Support\Facades\Blade::check('{$name}')): ?>";
|
||||
});
|
||||
|
||||
$this->directive('end'.$name, function () {
|
||||
return '<?php endif; ?>';
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the result of a condition.
|
||||
*
|
||||
* @param string $name
|
||||
* @param array $parameters
|
||||
* @return bool
|
||||
*/
|
||||
public function check($name, ...$parameters)
|
||||
{
|
||||
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)) {
|
||||
$this->component($value, null, $prefix);
|
||||
} else {
|
||||
$this->component($key, $value, $prefix);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the registered class component aliases.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getClassComponentAliases()
|
||||
{
|
||||
return $this->classComponentAliases;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a new anonymous component path.
|
||||
*
|
||||
* @param string $path
|
||||
* @param string|null $prefix
|
||||
* @return void
|
||||
*/
|
||||
public function anonymousComponentPath(string $path, string $prefix = null)
|
||||
{
|
||||
$prefixHash = md5($prefix ?: $path);
|
||||
|
||||
$this->anonymousComponentPaths[] = [
|
||||
'path' => $path,
|
||||
'prefix' => $prefix,
|
||||
'prefixHash' => $prefixHash,
|
||||
];
|
||||
|
||||
Container::getInstance()
|
||||
->make(ViewFactory::class)
|
||||
->addNamespace($prefixHash, $path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register an anonymous component namespace.
|
||||
*
|
||||
* @param string $directory
|
||||
* @param string|null $prefix
|
||||
* @return void
|
||||
*/
|
||||
public function anonymousComponentNamespace(string $directory, string $prefix = null)
|
||||
{
|
||||
$prefix ??= $directory;
|
||||
|
||||
$this->anonymousComponentNamespaces[$prefix] = Str::of($directory)
|
||||
->replace('/', '.')
|
||||
->trim('. ')
|
||||
->toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a class-based component namespace.
|
||||
*
|
||||
* @param string $namespace
|
||||
* @param string $prefix
|
||||
* @return void
|
||||
*/
|
||||
public function componentNamespace($namespace, $prefix)
|
||||
{
|
||||
$this->classComponentNamespaces[$prefix] = $namespace;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the registered anonymous component paths.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getAnonymousComponentPaths()
|
||||
{
|
||||
return $this->anonymousComponentPaths;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the registered anonymous component namespaces.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getAnonymousComponentNamespaces()
|
||||
{
|
||||
return $this->anonymousComponentNamespaces;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the registered class component namespaces.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getClassComponentNamespaces()
|
||||
{
|
||||
return $this->classComponentNamespaces;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a component alias directive.
|
||||
*
|
||||
* @param string $path
|
||||
* @param string|null $alias
|
||||
* @return void
|
||||
*/
|
||||
public function aliasComponent($path, $alias = null)
|
||||
{
|
||||
$alias = $alias ?: Arr::last(explode('.', $path));
|
||||
|
||||
$this->directive($alias, function ($expression) use ($path) {
|
||||
return $expression
|
||||
? "<?php \$__env->startComponent('{$path}', {$expression}); ?>"
|
||||
: "<?php \$__env->startComponent('{$path}'); ?>";
|
||||
});
|
||||
|
||||
$this->directive('end'.$alias, function ($expression) {
|
||||
return '<?php echo $__env->renderComponent(); ?>';
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Register an include alias directive.
|
||||
*
|
||||
* @param string $path
|
||||
* @param string|null $alias
|
||||
* @return void
|
||||
*/
|
||||
public function include($path, $alias = null)
|
||||
{
|
||||
$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));
|
||||
|
||||
$this->directive($alias, function ($expression) use ($path) {
|
||||
$expression = $this->stripParentheses($expression) ?: '[]';
|
||||
|
||||
return "<?php echo \$__env->make('{$path}', {$expression}, \Illuminate\Support\Arr::except(get_defined_vars(), ['__data', '__path']))->render(); ?>";
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a handler for custom directives.
|
||||
*
|
||||
* @param string $name
|
||||
* @param callable $handler
|
||||
* @return void
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function directive($name, callable $handler)
|
||||
{
|
||||
if (! preg_match('/^\w+(?:::\w+)?$/x', $name)) {
|
||||
throw new InvalidArgumentException("The directive name [{$name}] is not valid. Directive names must only contain alphanumeric characters and underscores.");
|
||||
}
|
||||
|
||||
$this->customDirectives[$name] = $handler;
|
||||
}
|
||||
|
||||
@@ -367,6 +850,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.
|
||||
*
|
||||
@@ -377,4 +871,34 @@ class BladeCompiler extends Compiler implements CompilerInterface
|
||||
{
|
||||
$this->echoFormat = $format;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the "echo" format to double encode entities.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function withDoubleEncoding()
|
||||
{
|
||||
$this->setEchoFormat('e(%s, true)');
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the "echo" format to not double encode entities.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function withoutDoubleEncoding()
|
||||
{
|
||||
$this->setEchoFormat('e(%s, false)');
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicate that component tags should not be compiled.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function withoutComponentTags()
|
||||
{
|
||||
$this->compilesComponentTags = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,35 +2,65 @@
|
||||
|
||||
namespace Illuminate\View\Compilers;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use Illuminate\Filesystem\Filesystem;
|
||||
use Illuminate\Support\Str;
|
||||
use InvalidArgumentException;
|
||||
|
||||
abstract class Compiler
|
||||
{
|
||||
/**
|
||||
* The Filesystem instance.
|
||||
* The filesystem instance.
|
||||
*
|
||||
* @var \Illuminate\Filesystem\Filesystem
|
||||
*/
|
||||
protected $files;
|
||||
|
||||
/**
|
||||
* Get the cache path for the compiled views.
|
||||
* The cache path for the compiled views.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $cachePath;
|
||||
|
||||
/**
|
||||
* The base path that should be removed from paths before hashing.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $basePath;
|
||||
|
||||
/**
|
||||
* Determines if compiled views should be cached.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $shouldCache;
|
||||
|
||||
/**
|
||||
* The compiled view file extension.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $compiledExtension = 'php';
|
||||
|
||||
/**
|
||||
* Create a new compiler instance.
|
||||
*
|
||||
* @param \Illuminate\Filesystem\Filesystem $files
|
||||
* @param string $cachePath
|
||||
* @param string $basePath
|
||||
* @param bool $shouldCache
|
||||
* @param string $compiledExtension
|
||||
* @return void
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function __construct(Filesystem $files, $cachePath)
|
||||
public function __construct(
|
||||
Filesystem $files,
|
||||
$cachePath,
|
||||
$basePath = '',
|
||||
$shouldCache = true,
|
||||
$compiledExtension = 'php')
|
||||
{
|
||||
if (! $cachePath) {
|
||||
throw new InvalidArgumentException('Please provide a valid cache path.');
|
||||
@@ -38,6 +68,9 @@ abstract class Compiler
|
||||
|
||||
$this->files = $files;
|
||||
$this->cachePath = $cachePath;
|
||||
$this->basePath = $basePath;
|
||||
$this->shouldCache = $shouldCache;
|
||||
$this->compiledExtension = $compiledExtension;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -48,7 +81,7 @@ abstract class Compiler
|
||||
*/
|
||||
public function getCompiledPath($path)
|
||||
{
|
||||
return $this->cachePath.'/'.sha1($path).'.php';
|
||||
return $this->cachePath.'/'.sha1('v2'.Str::after($path, $this->basePath)).'.'.$this->compiledExtension;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -59,6 +92,10 @@ abstract class Compiler
|
||||
*/
|
||||
public function isExpired($path)
|
||||
{
|
||||
if (! $this->shouldCache) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$compiled = $this->getCompiledPath($path);
|
||||
|
||||
// If the compiled file doesn't exist we will indicate that the view is expired
|
||||
@@ -71,4 +108,17 @@ abstract class Compiler
|
||||
return $this->files->lastModified($path) >=
|
||||
$this->files->lastModified($compiled);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the compiled file directory if necessary.
|
||||
*
|
||||
* @param string $path
|
||||
* @return void
|
||||
*/
|
||||
protected function ensureCompiledDirectoryExists($path)
|
||||
{
|
||||
if (! $this->files->exists(dirname($path))) {
|
||||
$this->files->makeDirectory(dirname($path), 0777, true, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
755
vendor/laravel/framework/src/Illuminate/View/Compilers/ComponentTagCompiler.php
vendored
Normal file
755
vendor/laravel/framework/src/Illuminate/View/Compilers/ComponentTagCompiler.php
vendored
Normal file
@@ -0,0 +1,755 @@
|
||||
<?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\DynamicComponent;
|
||||
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 component class namespaces.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $namespaces = [];
|
||||
|
||||
/**
|
||||
* The "bind:" attributes that have been compiled for the current component.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $boundAttributes = [];
|
||||
|
||||
/**
|
||||
* Create a new component tag compiler.
|
||||
*
|
||||
* @param array $aliases
|
||||
* @param array $namespaces
|
||||
* @param \Illuminate\View\Compilers\BladeCompiler|null $blade
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(array $aliases = [], array $namespaces = [], ?BladeCompiler $blade = null)
|
||||
{
|
||||
$this->aliases = $aliases;
|
||||
$this->namespaces = $namespaces;
|
||||
|
||||
$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+
|
||||
(?:
|
||||
(?:
|
||||
@(?:class)(\( (?: (?>[^()]+) | (?-1) )* \))
|
||||
)
|
||||
|
|
||||
(?:
|
||||
\{\{\s*\\\$attributes(?:[^}]+?)?\s*\}\}
|
||||
)
|
||||
|
|
||||
(?:
|
||||
(\:\\\$)(\w+)
|
||||
)
|
||||
|
|
||||
(?:
|
||||
[\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+
|
||||
(?:
|
||||
(?:
|
||||
@(?:class)(\( (?: (?>[^()]+) | (?-1) )* \))
|
||||
)
|
||||
|
|
||||
(?:
|
||||
\{\{\s*\\\$attributes(?:[^}]+?)?\s*\}\}
|
||||
)
|
||||
|
|
||||
(?:
|
||||
(\:\\\$)(\w+)
|
||||
)
|
||||
|
|
||||
(?:
|
||||
[\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##END-COMPONENT-CLASS##";
|
||||
}, $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 exist 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)) {
|
||||
$view = Str::startsWith($component, 'mail::')
|
||||
? "\$__env->getContainer()->make(Illuminate\\View\\Factory::class)->make('{$component}')"
|
||||
: "'$class'";
|
||||
|
||||
$parameters = [
|
||||
'view' => $view,
|
||||
'data' => '['.$this->attributesToString($data->all(), $escapeBound = false).']',
|
||||
];
|
||||
|
||||
$class = AnonymousComponent::class;
|
||||
} else {
|
||||
$parameters = $data->all();
|
||||
}
|
||||
|
||||
return "##BEGIN-COMPONENT-CLASS##@component('{$class}', '{$component}', [".$this->attributesToString($parameters, $escapeBound = false).'])
|
||||
<?php if (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag && $constructor = (new ReflectionClass('.$class.'::class))->getConstructor()): ?>
|
||||
<?php $attributes = $attributes->except(collect($constructor->getParameters())->map->getName()->all()); ?>
|
||||
<?php endif; ?>
|
||||
<?php $component->withAttributes(['.$this->attributesToString($attributes->all(), $escapeAttributes = $class !== DynamicComponent::class).']); ?>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the component class for a given component alias.
|
||||
*
|
||||
* @param string $component
|
||||
* @return string
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public 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 = $this->findClassByComponent($component)) {
|
||||
return $class;
|
||||
}
|
||||
|
||||
if (class_exists($class = $this->guessClassName($component))) {
|
||||
return $class;
|
||||
}
|
||||
|
||||
if (! is_null($guess = $this->guessAnonymousComponentUsingNamespaces($viewFactory, $component)) ||
|
||||
! is_null($guess = $this->guessAnonymousComponentUsingPaths($viewFactory, $component))) {
|
||||
return $guess;
|
||||
}
|
||||
|
||||
if (Str::startsWith($component, 'mail::')) {
|
||||
return $component;
|
||||
}
|
||||
|
||||
throw new InvalidArgumentException(
|
||||
"Unable to locate a class or view for component [{$component}]."
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to find an anonymous component using the registered anonymous component paths.
|
||||
*
|
||||
* @param \Illuminate\Contracts\View\Factory $viewFactory
|
||||
* @param string $component
|
||||
* @return string|null
|
||||
*/
|
||||
protected function guessAnonymousComponentUsingPaths(Factory $viewFactory, string $component)
|
||||
{
|
||||
$delimiter = ViewFinderInterface::HINT_PATH_DELIMITER;
|
||||
|
||||
foreach ($this->blade->getAnonymousComponentPaths() as $path) {
|
||||
try {
|
||||
if (str_contains($component, $delimiter) &&
|
||||
! str_starts_with($component, $path['prefix'].$delimiter)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$formattedComponent = str_starts_with($component, $path['prefix'].$delimiter)
|
||||
? Str::after($component, $delimiter)
|
||||
: $component;
|
||||
|
||||
if (! is_null($guess = match (true) {
|
||||
$viewFactory->exists($guess = $path['prefixHash'].$delimiter.$formattedComponent) => $guess,
|
||||
$viewFactory->exists($guess = $path['prefixHash'].$delimiter.$formattedComponent.'.index') => $guess,
|
||||
default => null,
|
||||
})) {
|
||||
return $guess;
|
||||
}
|
||||
} catch (InvalidArgumentException $e) {
|
||||
//
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to find an anonymous component using the registered anonymous component namespaces.
|
||||
*
|
||||
* @param \Illuminate\Contracts\View\Factory $viewFactory
|
||||
* @param string $component
|
||||
* @return string|null
|
||||
*/
|
||||
protected function guessAnonymousComponentUsingNamespaces(Factory $viewFactory, string $component)
|
||||
{
|
||||
return collect($this->blade->getAnonymousComponentNamespaces())
|
||||
->filter(function ($directory, $prefix) use ($component) {
|
||||
return Str::startsWith($component, $prefix.'::');
|
||||
})
|
||||
->prepend('components', $component)
|
||||
->reduce(function ($carry, $directory, $prefix) use ($component, $viewFactory) {
|
||||
if (! is_null($carry)) {
|
||||
return $carry;
|
||||
}
|
||||
|
||||
$componentName = Str::after($component, $prefix.'::');
|
||||
|
||||
if ($viewFactory->exists($view = $this->guessViewName($componentName, $directory))) {
|
||||
return $view;
|
||||
}
|
||||
|
||||
if ($viewFactory->exists($view = $this->guessViewName($componentName, $directory).'.index')) {
|
||||
return $view;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the class for the given component using the registered namespaces.
|
||||
*
|
||||
* @param string $component
|
||||
* @return string|null
|
||||
*/
|
||||
public function findClassByComponent(string $component)
|
||||
{
|
||||
$segments = explode('::', $component);
|
||||
|
||||
$prefix = $segments[0];
|
||||
|
||||
if (! isset($this->namespaces[$prefix], $segments[1])) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (class_exists($class = $this->namespaces[$prefix].'\\'.$this->formatClassName($segments[1]))) {
|
||||
return $class;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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();
|
||||
|
||||
$class = $this->formatClassName($component);
|
||||
|
||||
return $namespace.'View\\Components\\'.$class;
|
||||
}
|
||||
|
||||
/**
|
||||
* Format the class name for the given component.
|
||||
*
|
||||
* @param string $component
|
||||
* @return string
|
||||
*/
|
||||
public function formatClassName(string $component)
|
||||
{
|
||||
$componentPieces = array_map(function ($componentPiece) {
|
||||
return ucfirst(Str::camel($componentPiece));
|
||||
}, explode('.', $component));
|
||||
|
||||
return implode('\\', $componentPieces);
|
||||
}
|
||||
|
||||
/**
|
||||
* Guess the view name for the given component.
|
||||
*
|
||||
* @param string $name
|
||||
* @param string $prefix
|
||||
* @return string
|
||||
*/
|
||||
public function guessViewName($name, $prefix = 'components.')
|
||||
{
|
||||
if (! Str::endsWith($prefix, '.')) {
|
||||
$prefix .= '.';
|
||||
}
|
||||
|
||||
$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
|
||||
*/
|
||||
public function partitionDataAndAttributes($class, array $attributes)
|
||||
{
|
||||
// If the class doesn't exist, we'll assume it is 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##END-COMPONENT-CLASS##', $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the slot tags within the given string.
|
||||
*
|
||||
* @param string $value
|
||||
* @return string
|
||||
*/
|
||||
public function compileSlots(string $value)
|
||||
{
|
||||
$pattern = "/
|
||||
<
|
||||
\s*
|
||||
x[\-\:]slot
|
||||
(?:\:(?<inlineName>\w+(?:-\w+)*))?
|
||||
(?:\s+(:?)name=(?<name>(\"[^\"]+\"|\\\'[^\\\']+\\\'|[^\s>]+)))?
|
||||
(?<attributes>
|
||||
(?:
|
||||
\s+
|
||||
(?:
|
||||
(?:
|
||||
@(?:class)(\( (?: (?>[^()]+) | (?-1) )* \))
|
||||
)
|
||||
|
|
||||
(?:
|
||||
\{\{\s*\\\$attributes(?:[^}]+?)?\s*\}\}
|
||||
)
|
||||
|
|
||||
(?:
|
||||
[\w\-:.@]+
|
||||
(
|
||||
=
|
||||
(?:
|
||||
\\\"[^\\\"]*\\\"
|
||||
|
|
||||
\'[^\']*\'
|
||||
|
|
||||
[^\'\\\"=<>]+
|
||||
)
|
||||
)?
|
||||
)
|
||||
)
|
||||
)*
|
||||
\s*
|
||||
)
|
||||
(?<![\/=\-])
|
||||
>
|
||||
/x";
|
||||
|
||||
$value = preg_replace_callback($pattern, function ($matches) {
|
||||
$name = $this->stripQuotes($matches['inlineName'] ?: $matches['name']);
|
||||
|
||||
if (Str::contains($name, '-') && ! empty($matches['inlineName'])) {
|
||||
$name = Str::camel($name);
|
||||
}
|
||||
|
||||
if ($matches[2] !== ':') {
|
||||
$name = "'{$name}'";
|
||||
}
|
||||
|
||||
$this->boundAttributes = [];
|
||||
|
||||
$attributes = $this->getAttributesFromAttributeString($matches['attributes']);
|
||||
|
||||
return " @slot({$name}, null, [".$this->attributesToString($attributes).']) ';
|
||||
}, $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->parseShortAttributeSyntax($attributeString);
|
||||
$attributeString = $this->parseAttributeBag($attributeString);
|
||||
$attributeString = $this->parseComponentTagClassStatements($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_starts_with($attribute, 'bind:')) {
|
||||
$attribute = Str::after($attribute, 'bind:');
|
||||
|
||||
$this->boundAttributes[$attribute] = true;
|
||||
} else {
|
||||
$value = "'".$this->compileAttributeEchos($value)."'";
|
||||
}
|
||||
|
||||
if (str_starts_with($attribute, '::')) {
|
||||
$attribute = substr($attribute, 1);
|
||||
}
|
||||
|
||||
return [$attribute => $value];
|
||||
})->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a short attribute syntax like :$foo into a fully-qualified syntax like :foo="$foo".
|
||||
*
|
||||
* @param string $value
|
||||
* @return string
|
||||
*/
|
||||
protected function parseShortAttributeSyntax(string $value)
|
||||
{
|
||||
$pattern = "/\s\:\\\$(\w+)/x";
|
||||
|
||||
return preg_replace_callback($pattern, function (array $matches) {
|
||||
return " :{$matches[1]}=\"\${$matches[1]}\"";
|
||||
}, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the attribute bag in a given attribute string into its fully-qualified syntax.
|
||||
*
|
||||
* @param string $attributeString
|
||||
* @return string
|
||||
*/
|
||||
protected function parseAttributeBag(string $attributeString)
|
||||
{
|
||||
$pattern = "/
|
||||
(?:^|\s+) # start of the string or whitespace between attributes
|
||||
\{\{\s*(\\\$attributes(?:[^}]+?(?<!\s))?)\s*\}\} # exact match of attributes variable being echoed
|
||||
/x";
|
||||
|
||||
return preg_replace($pattern, ' :attributes="$1"', $attributeString);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse @class statements in a given attribute string into their fully-qualified syntax.
|
||||
*
|
||||
* @param string $attributeString
|
||||
* @return string
|
||||
*/
|
||||
protected function parseComponentTagClassStatements(string $attributeString)
|
||||
{
|
||||
return preg_replace_callback(
|
||||
'/@(class)(\( ( (?>[^()]+) | (?2) )* \))/x', function ($match) {
|
||||
if ($match[1] === 'class') {
|
||||
$match[2] = str_replace('"', "'", $match[2]);
|
||||
|
||||
return ":class=\"\Illuminate\Support\Arr::toCssClasses{$match[2]}\"";
|
||||
}
|
||||
|
||||
return $match[0];
|
||||
}, $attributeString
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 single colon
|
||||
([\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;
|
||||
}
|
||||
}
|
||||
@@ -26,6 +26,17 @@ trait CompilesAuthorizations
|
||||
return "<?php if (app(\Illuminate\\Contracts\\Auth\\Access\\Gate::class)->denies{$expression}): ?>";
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the canany statements into valid PHP.
|
||||
*
|
||||
* @param string $expression
|
||||
* @return string
|
||||
*/
|
||||
protected function compileCanany($expression)
|
||||
{
|
||||
return "<?php if (app(\Illuminate\\Contracts\\Auth\\Access\\Gate::class)->any{$expression}): ?>";
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the else-can statements into valid PHP.
|
||||
*
|
||||
@@ -48,6 +59,17 @@ trait CompilesAuthorizations
|
||||
return "<?php elseif (app(\Illuminate\\Contracts\\Auth\\Access\\Gate::class)->denies{$expression}): ?>";
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the else-canany statements into valid PHP.
|
||||
*
|
||||
* @param string $expression
|
||||
* @return string
|
||||
*/
|
||||
protected function compileElsecanany($expression)
|
||||
{
|
||||
return "<?php elseif (app(\Illuminate\\Contracts\\Auth\\Access\\Gate::class)->any{$expression}): ?>";
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the end-can statements into valid PHP.
|
||||
*
|
||||
@@ -67,4 +89,14 @@ trait CompilesAuthorizations
|
||||
{
|
||||
return '<?php endif; ?>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the end-canany statements into valid PHP.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function compileEndcanany()
|
||||
{
|
||||
return '<?php endif; ?>';
|
||||
}
|
||||
}
|
||||
|
||||
19
vendor/laravel/framework/src/Illuminate/View/Compilers/Concerns/CompilesClasses.php
vendored
Normal file
19
vendor/laravel/framework/src/Illuminate/View/Compilers/Concerns/CompilesClasses.php
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\View\Compilers\Concerns;
|
||||
|
||||
trait CompilesClasses
|
||||
{
|
||||
/**
|
||||
* Compile the conditional class statement into valid PHP.
|
||||
*
|
||||
* @param string $expression
|
||||
* @return string
|
||||
*/
|
||||
protected function compileClass($expression)
|
||||
{
|
||||
$expression = is_null($expression) ? '([])' : $expression;
|
||||
|
||||
return "class=\"<?php echo \Illuminate\Support\Arr::toCssClasses{$expression} ?>\"";
|
||||
}
|
||||
}
|
||||
@@ -2,8 +2,19 @@
|
||||
|
||||
namespace Illuminate\View\Compilers\Concerns;
|
||||
|
||||
use Illuminate\Contracts\Support\CanBeEscapedWhenCastToString;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\View\ComponentAttributeBag;
|
||||
|
||||
trait CompilesComponents
|
||||
{
|
||||
/**
|
||||
* The component name hash stack.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected static $componentHashStack = [];
|
||||
|
||||
/**
|
||||
* Compile the component statements into valid PHP.
|
||||
*
|
||||
@@ -12,9 +23,54 @@ trait CompilesComponents
|
||||
*/
|
||||
protected function compileComponent($expression)
|
||||
{
|
||||
[$component, $alias, $data] = str_contains($expression, ',')
|
||||
? 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 = '.$component.'::resolve('.($data ?: '[]').' + (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag ? (array) $attributes->getIterator() : [])); ?>',
|
||||
'<?php $component->withName('.$alias.'); ?>',
|
||||
'<?php if ($component->shouldRender()): ?>',
|
||||
'<?php $__env->startComponent($component->resolveView(), $component->data()); ?>',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the end-component statements into valid PHP.
|
||||
*
|
||||
@@ -25,6 +81,24 @@ trait CompilesComponents
|
||||
return '<?php echo $__env->renderComponent(); ?>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the end-component statements into valid PHP.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function compileEndComponentClass()
|
||||
{
|
||||
$hash = array_pop(static::$componentHashStack);
|
||||
|
||||
return $this->compileEndComponent()."\n".implode("\n", [
|
||||
'<?php endif; ?>',
|
||||
'<?php if (isset($__componentOriginal'.$hash.')): ?>',
|
||||
'<?php $component = $__componentOriginal'.$hash.'; ?>',
|
||||
'<?php unset($__componentOriginal'.$hash.'); ?>',
|
||||
'<?php endif; ?>',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the slot statements into valid PHP.
|
||||
*
|
||||
@@ -45,4 +119,80 @@ trait CompilesComponents
|
||||
{
|
||||
return '<?php $__env->endSlot(); ?>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the component-first statements into valid PHP.
|
||||
*
|
||||
* @param string $expression
|
||||
* @return string
|
||||
*/
|
||||
protected function compileComponentFirst($expression)
|
||||
{
|
||||
return "<?php \$__env->startComponentFirst{$expression}; ?>";
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the end-component-first statements into valid PHP.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function compileEndComponentFirst()
|
||||
{
|
||||
return $this->compileEndComponent();
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the prop statement into valid PHP.
|
||||
*
|
||||
* @param string $expression
|
||||
* @return string
|
||||
*/
|
||||
protected function compileProps($expression)
|
||||
{
|
||||
return "<?php \$attributes ??= new \\Illuminate\\View\\ComponentAttributeBag; ?>
|
||||
<?php foreach(\$attributes->onlyProps{$expression} as \$__key => \$__value) {
|
||||
\$\$__key = \$\$__key ?? \$__value;
|
||||
} ?>
|
||||
<?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); ?>";
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the aware statement into valid PHP.
|
||||
*
|
||||
* @param string $expression
|
||||
* @return string
|
||||
*/
|
||||
protected function compileAware($expression)
|
||||
{
|
||||
return "<?php foreach ({$expression} as \$__key => \$__value) {
|
||||
\$__consumeVariable = is_string(\$__key) ? \$__key : \$__value;
|
||||
\$\$__consumeVariable = is_string(\$__key) ? \$__env->getConsumableComponentData(\$__key, \$__value) : \$__env->getConsumableComponentData(\$__value);
|
||||
} ?>";
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanitize the given component attribute value.
|
||||
*
|
||||
* @param mixed $value
|
||||
* @return mixed
|
||||
*/
|
||||
public static function sanitizeComponentAttribute($value)
|
||||
{
|
||||
if ($value instanceof CanBeEscapedWhenCastToString) {
|
||||
return $value->escapeWhenCastingToString();
|
||||
}
|
||||
|
||||
return is_string($value) ||
|
||||
(is_object($value) && ! $value instanceof ComponentAttributeBag && method_exists($value, '__toString'))
|
||||
? e($value)
|
||||
: $value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,18 +2,16 @@
|
||||
|
||||
namespace Illuminate\View\Compilers\Concerns;
|
||||
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
trait CompilesConditionals
|
||||
{
|
||||
/**
|
||||
* Compile the has-section statements into valid PHP.
|
||||
* Identifier for the first case in the switch statement.
|
||||
*
|
||||
* @param string $expression
|
||||
* @return string
|
||||
* @var bool
|
||||
*/
|
||||
protected function compileHasSection($expression)
|
||||
{
|
||||
return "<?php if (! empty(trim(\$__env->yieldContent{$expression}))): ?>";
|
||||
}
|
||||
protected $firstCaseInSwitch = true;
|
||||
|
||||
/**
|
||||
* Compile the if-auth statements into valid PHP.
|
||||
@@ -28,6 +26,19 @@ trait CompilesConditionals
|
||||
return "<?php if(auth()->guard{$guard}->check()): ?>";
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the else-auth statements into valid PHP.
|
||||
*
|
||||
* @param string|null $guard
|
||||
* @return string
|
||||
*/
|
||||
protected function compileElseAuth($guard = null)
|
||||
{
|
||||
$guard = is_null($guard) ? '()' : $guard;
|
||||
|
||||
return "<?php elseif(auth()->guard{$guard}->check()): ?>";
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the end-auth statements into valid PHP.
|
||||
*
|
||||
@@ -38,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.
|
||||
*
|
||||
@@ -51,6 +103,19 @@ trait CompilesConditionals
|
||||
return "<?php if(auth()->guard{$guard}->guest()): ?>";
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the else-guest statements into valid PHP.
|
||||
*
|
||||
* @param string|null $guard
|
||||
* @return string
|
||||
*/
|
||||
protected function compileElseGuest($guard = null)
|
||||
{
|
||||
$guard = is_null($guard) ? '()' : $guard;
|
||||
|
||||
return "<?php elseif(auth()->guard{$guard}->guest()): ?>";
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the end-guest statements into valid PHP.
|
||||
*
|
||||
@@ -61,6 +126,28 @@ trait CompilesConditionals
|
||||
return '<?php endif; ?>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the has-section statements into valid PHP.
|
||||
*
|
||||
* @param string $expression
|
||||
* @return string
|
||||
*/
|
||||
protected function compileHasSection($expression)
|
||||
{
|
||||
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.
|
||||
*
|
||||
@@ -144,4 +231,155 @@ trait CompilesConditionals
|
||||
{
|
||||
return '<?php endif; ?>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the switch statements into valid PHP.
|
||||
*
|
||||
* @param string $expression
|
||||
* @return string
|
||||
*/
|
||||
protected function compileSwitch($expression)
|
||||
{
|
||||
$this->firstCaseInSwitch = true;
|
||||
|
||||
return "<?php switch{$expression}:";
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the case statements into valid PHP.
|
||||
*
|
||||
* @param string $expression
|
||||
* @return string
|
||||
*/
|
||||
protected function compileCase($expression)
|
||||
{
|
||||
if ($this->firstCaseInSwitch) {
|
||||
$this->firstCaseInSwitch = false;
|
||||
|
||||
return "case {$expression}: ?>";
|
||||
}
|
||||
|
||||
return "<?php case {$expression}: ?>";
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the default statements in switch case into valid PHP.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function compileDefault()
|
||||
{
|
||||
return '<?php default: ?>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the end switch statements into valid PHP.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function compileEndSwitch()
|
||||
{
|
||||
return '<?php endswitch; ?>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile a once block into valid PHP.
|
||||
*
|
||||
* @param string|null $id
|
||||
* @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; ?>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile a selected block into valid PHP.
|
||||
*
|
||||
* @param string $condition
|
||||
* @return string
|
||||
*/
|
||||
protected function compileSelected($condition)
|
||||
{
|
||||
return "<?php if{$condition}: echo 'selected'; endif; ?>";
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile a checked block into valid PHP.
|
||||
*
|
||||
* @param string $condition
|
||||
* @return string
|
||||
*/
|
||||
protected function compileChecked($condition)
|
||||
{
|
||||
return "<?php if{$condition}: echo 'checked'; endif; ?>";
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile a disabled block into valid PHP.
|
||||
*
|
||||
* @param string $condition
|
||||
* @return string
|
||||
*/
|
||||
protected function compileDisabled($condition)
|
||||
{
|
||||
return "<?php if{$condition}: echo 'disabled'; endif; ?>";
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile a required block into valid PHP.
|
||||
*
|
||||
* @param string $condition
|
||||
* @return string
|
||||
*/
|
||||
protected function compileRequired($condition)
|
||||
{
|
||||
return "<?php if{$condition}: echo 'required'; endif; ?>";
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile a readonly block into valid PHP.
|
||||
*
|
||||
* @param string $condition
|
||||
* @return string
|
||||
*/
|
||||
protected function compileReadonly($condition)
|
||||
{
|
||||
return "<?php if{$condition}: echo 'readonly'; endif; ?>";
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the push statements into valid PHP.
|
||||
*
|
||||
* @param string $expression
|
||||
* @return string
|
||||
*/
|
||||
protected function compilePushIf($expression)
|
||||
{
|
||||
$parts = explode(',', $this->stripParentheses($expression), 2);
|
||||
|
||||
return "<?php if({$parts[0]}): \$__env->startPush({$parts[1]}); ?>";
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the end-push statements into valid PHP.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function compileEndPushIf()
|
||||
{
|
||||
return '<?php $__env->stopPush(); endif; ?>';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,15 +2,41 @@
|
||||
|
||||
namespace Illuminate\View\Compilers\Concerns;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
trait CompilesEchos
|
||||
{
|
||||
/**
|
||||
* Custom rendering callbacks for stringable objects.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $echoHandlers = [];
|
||||
|
||||
/**
|
||||
* Add a handler to be executed before echoing a given class.
|
||||
*
|
||||
* @param string|callable $class
|
||||
* @param callable|null $handler
|
||||
* @return void
|
||||
*/
|
||||
public function stringable($class, $handler = null)
|
||||
{
|
||||
if ($class instanceof Closure) {
|
||||
[$class, $handler] = [$this->firstClosureParameterType($class), $class];
|
||||
}
|
||||
|
||||
$this->echoHandlers[$class] = $handler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile Blade echos into valid PHP.
|
||||
*
|
||||
* @param string $value
|
||||
* @return string
|
||||
*/
|
||||
protected function compileEchos($value)
|
||||
public function compileEchos($value)
|
||||
{
|
||||
foreach ($this->getEchoMethods() as $method) {
|
||||
$value = $this->$method($value);
|
||||
@@ -46,7 +72,9 @@ trait CompilesEchos
|
||||
$callback = function ($matches) {
|
||||
$whitespace = empty($matches[3]) ? '' : $matches[3].$matches[3];
|
||||
|
||||
return $matches[1] ? substr($matches[0], 1) : "<?php echo {$this->compileEchoDefaults($matches[2])}; ?>{$whitespace}";
|
||||
return $matches[1]
|
||||
? substr($matches[0], 1)
|
||||
: "<?php echo {$this->wrapInEchoHandler($matches[2])}; ?>{$whitespace}";
|
||||
};
|
||||
|
||||
return preg_replace_callback($pattern, $callback, $value);
|
||||
@@ -65,7 +93,7 @@ trait CompilesEchos
|
||||
$callback = function ($matches) {
|
||||
$whitespace = empty($matches[3]) ? '' : $matches[3].$matches[3];
|
||||
|
||||
$wrapped = sprintf($this->echoFormat, $this->compileEchoDefaults($matches[2]));
|
||||
$wrapped = sprintf($this->echoFormat, $this->wrapInEchoHandler($matches[2]));
|
||||
|
||||
return $matches[1] ? substr($matches[0], 1) : "<?php echo {$wrapped}; ?>{$whitespace}";
|
||||
};
|
||||
@@ -86,20 +114,54 @@ trait CompilesEchos
|
||||
$callback = function ($matches) {
|
||||
$whitespace = empty($matches[3]) ? '' : $matches[3].$matches[3];
|
||||
|
||||
return $matches[1] ? $matches[0] : "<?php echo e({$this->compileEchoDefaults($matches[2])}); ?>{$whitespace}";
|
||||
return $matches[1]
|
||||
? $matches[0]
|
||||
: "<?php echo e({$this->wrapInEchoHandler($matches[2])}); ?>{$whitespace}";
|
||||
};
|
||||
|
||||
return preg_replace_callback($pattern, $callback, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the default values for the echo statement.
|
||||
* Add an instance of the blade echo handler to the start of the compiled string.
|
||||
*
|
||||
* @param string $result
|
||||
* @return string
|
||||
*/
|
||||
protected function addBladeCompilerVariable($result)
|
||||
{
|
||||
return "<?php \$__bladeCompiler = app('blade.compiler'); ?>".$result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrap the echoable value in an echo handler if applicable.
|
||||
*
|
||||
* @param string $value
|
||||
* @return string
|
||||
*/
|
||||
public function compileEchoDefaults($value)
|
||||
protected function wrapInEchoHandler($value)
|
||||
{
|
||||
return preg_replace('/^(?=\$)(.+?)(?:\s+or\s+)(.+?)$/s', 'isset($1) ? $1 : $2', $value);
|
||||
$value = Str::of($value)
|
||||
->trim()
|
||||
->when(str_ends_with($value, ';'), function ($str) {
|
||||
return $str->beforeLast(';');
|
||||
});
|
||||
|
||||
return empty($this->echoHandlers) ? $value : '$__bladeCompiler->applyEchoHandler('.$value.')';
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the echo handler for the value if it exists.
|
||||
*
|
||||
* @param string $value
|
||||
* @return string
|
||||
*/
|
||||
public function applyEchoHandler($value)
|
||||
{
|
||||
if (is_object($value) && isset($this->echoHandlers[get_class($value)])) {
|
||||
return call_user_func($this->echoHandlers[get_class($value)], $value);
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
|
||||
37
vendor/laravel/framework/src/Illuminate/View/Compilers/Concerns/CompilesErrors.php
vendored
Normal file
37
vendor/laravel/framework/src/Illuminate/View/Compilers/Concerns/CompilesErrors.php
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\View\Compilers\Concerns;
|
||||
|
||||
trait CompilesErrors
|
||||
{
|
||||
/**
|
||||
* Compile the error statements into valid PHP.
|
||||
*
|
||||
* @param string $expression
|
||||
* @return string
|
||||
*/
|
||||
protected function compileError($expression)
|
||||
{
|
||||
$expression = $this->stripParentheses($expression);
|
||||
|
||||
return '<?php $__errorArgs = ['.$expression.'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? \'default\');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the enderror statements into valid PHP.
|
||||
*
|
||||
* @param string $expression
|
||||
* @return string
|
||||
*/
|
||||
protected function compileEnderror($expression)
|
||||
{
|
||||
return '<?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>';
|
||||
}
|
||||
}
|
||||
36
vendor/laravel/framework/src/Illuminate/View/Compilers/Concerns/CompilesFragments.php
vendored
Normal file
36
vendor/laravel/framework/src/Illuminate/View/Compilers/Concerns/CompilesFragments.php
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\View\Compilers\Concerns;
|
||||
|
||||
trait CompilesFragments
|
||||
{
|
||||
/**
|
||||
* The last compiled fragment.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $lastFragment;
|
||||
|
||||
/**
|
||||
* Compile the fragment statements into valid PHP.
|
||||
*
|
||||
* @param string $expression
|
||||
* @return string
|
||||
*/
|
||||
protected function compileFragment($expression)
|
||||
{
|
||||
$this->lastFragment = trim($expression, "()'\" ");
|
||||
|
||||
return "<?php \$__env->startFragment{$expression}; ?>";
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the end-fragment statements into valid PHP.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function compileEndfragment()
|
||||
{
|
||||
return '<?php echo $__env->stopFragment(); ?>';
|
||||
}
|
||||
}
|
||||
78
vendor/laravel/framework/src/Illuminate/View/Compilers/Concerns/CompilesHelpers.php
vendored
Normal file
78
vendor/laravel/framework/src/Illuminate/View/Compilers/Concerns/CompilesHelpers.php
vendored
Normal file
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\View\Compilers\Concerns;
|
||||
|
||||
use Illuminate\Foundation\Vite;
|
||||
|
||||
trait CompilesHelpers
|
||||
{
|
||||
/**
|
||||
* Compile the CSRF statements into valid PHP.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function compileCsrf()
|
||||
{
|
||||
return '<?php echo csrf_field(); ?>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the "dd" statements into valid PHP.
|
||||
*
|
||||
* @param string $arguments
|
||||
* @return string
|
||||
*/
|
||||
protected function compileDd($arguments)
|
||||
{
|
||||
return "<?php dd{$arguments}; ?>";
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the "dump" statements into valid PHP.
|
||||
*
|
||||
* @param string $arguments
|
||||
* @return string
|
||||
*/
|
||||
protected function compileDump($arguments)
|
||||
{
|
||||
return "<?php dump{$arguments}; ?>";
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the method statements into valid PHP.
|
||||
*
|
||||
* @param string $method
|
||||
* @return string
|
||||
*/
|
||||
protected function compileMethod($method)
|
||||
{
|
||||
return "<?php echo method_field{$method}; ?>";
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the "vite" statements into valid PHP.
|
||||
*
|
||||
* @param ?string $arguments
|
||||
* @return string
|
||||
*/
|
||||
protected function compileVite($arguments)
|
||||
{
|
||||
$arguments ??= '()';
|
||||
|
||||
$class = Vite::class;
|
||||
|
||||
return "<?php echo app('$class'){$arguments}; ?>";
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the "viteReactRefresh" statements into valid PHP.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function compileViteReactRefresh()
|
||||
{
|
||||
$class = Vite::class;
|
||||
|
||||
return "<?php echo app('$class')->reactRefresh(); ?>";
|
||||
}
|
||||
}
|
||||
@@ -25,7 +25,7 @@ trait CompilesIncludes
|
||||
{
|
||||
$expression = $this->stripParentheses($expression);
|
||||
|
||||
return "<?php echo \$__env->make({$expression}, array_except(get_defined_vars(), array('__data', '__path')))->render(); ?>";
|
||||
return "<?php echo \$__env->make({$expression}, \Illuminate\Support\Arr::except(get_defined_vars(), ['__data', '__path']))->render(); ?>";
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -38,19 +38,45 @@ trait CompilesIncludes
|
||||
{
|
||||
$expression = $this->stripParentheses($expression);
|
||||
|
||||
return "<?php if (\$__env->exists({$expression})) echo \$__env->make({$expression}, array_except(get_defined_vars(), array('__data', '__path')))->render(); ?>";
|
||||
return "<?php if (\$__env->exists({$expression})) echo \$__env->make({$expression}, \Illuminate\Support\Arr::except(get_defined_vars(), ['__data', '__path']))->render(); ?>";
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the include-when statements into valid PHP.
|
||||
*
|
||||
* @param string $expression
|
||||
* @param string $expression
|
||||
* @return string
|
||||
*/
|
||||
protected function compileIncludeWhen($expression)
|
||||
{
|
||||
$expression = $this->stripParentheses($expression);
|
||||
|
||||
return "<?php echo \$__env->renderWhen($expression, array_except(get_defined_vars(), array('__data', '__path'))); ?>";
|
||||
return "<?php echo \$__env->renderWhen($expression, \Illuminate\Support\Arr::except(get_defined_vars(), ['__data', '__path'])); ?>";
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the include-unless statements into valid PHP.
|
||||
*
|
||||
* @param string $expression
|
||||
* @return string
|
||||
*/
|
||||
protected function compileIncludeUnless($expression)
|
||||
{
|
||||
$expression = $this->stripParentheses($expression);
|
||||
|
||||
return "<?php echo \$__env->renderUnless($expression, \Illuminate\Support\Arr::except(get_defined_vars(), ['__data', '__path'])); ?>";
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the include-first statements into valid PHP.
|
||||
*
|
||||
* @param string $expression
|
||||
* @return string
|
||||
*/
|
||||
protected function compileIncludeFirst($expression)
|
||||
{
|
||||
$expression = $this->stripParentheses($expression);
|
||||
|
||||
return "<?php echo \$__env->first({$expression}, \Illuminate\Support\Arr::except(get_defined_vars(), ['__data', '__path']))->render(); ?>";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,12 +12,12 @@ trait CompilesInjections
|
||||
*/
|
||||
protected function compileInject($expression)
|
||||
{
|
||||
$segments = explode(',', preg_replace("/[\(\)\\\"\']/", '', $expression));
|
||||
$segments = explode(',', preg_replace("/[\(\)]/", '', $expression));
|
||||
|
||||
$variable = trim($segments[0]);
|
||||
$variable = trim($segments[0], " '\"");
|
||||
|
||||
$service = trim($segments[1]);
|
||||
|
||||
return "<?php \${$variable} = app('{$service}'); ?>";
|
||||
return "<?php \${$variable} = app({$service}); ?>";
|
||||
}
|
||||
}
|
||||
|
||||
22
vendor/laravel/framework/src/Illuminate/View/Compilers/Concerns/CompilesJs.php
vendored
Normal file
22
vendor/laravel/framework/src/Illuminate/View/Compilers/Concerns/CompilesJs.php
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\View\Compilers\Concerns;
|
||||
|
||||
use Illuminate\Support\Js;
|
||||
|
||||
trait CompilesJs
|
||||
{
|
||||
/**
|
||||
* Compile the "@js" directive into valid PHP.
|
||||
*
|
||||
* @param string $expression
|
||||
* @return string
|
||||
*/
|
||||
protected function compileJs(string $expression)
|
||||
{
|
||||
return sprintf(
|
||||
"<?php echo \%s::from(%s)->toHtml() ?>",
|
||||
Js::class, $this->stripParentheses($expression)
|
||||
);
|
||||
}
|
||||
}
|
||||
30
vendor/laravel/framework/src/Illuminate/View/Compilers/Concerns/CompilesJson.php
vendored
Normal file
30
vendor/laravel/framework/src/Illuminate/View/Compilers/Concerns/CompilesJson.php
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\View\Compilers\Concerns;
|
||||
|
||||
trait CompilesJson
|
||||
{
|
||||
/**
|
||||
* The default JSON encoding options.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $encodingOptions = JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_AMP | JSON_HEX_QUOT;
|
||||
|
||||
/**
|
||||
* Compile the JSON statement into valid PHP.
|
||||
*
|
||||
* @param string $expression
|
||||
* @return string
|
||||
*/
|
||||
protected function compileJson($expression)
|
||||
{
|
||||
$parts = explode(',', $this->stripParentheses($expression));
|
||||
|
||||
$options = isset($parts[1]) ? trim($parts[1]) : $this->encodingOptions;
|
||||
|
||||
$depth = isset($parts[2]) ? trim($parts[2]) : 512;
|
||||
|
||||
return "<?php echo json_encode($parts[0], $options, $depth) ?>";
|
||||
}
|
||||
}
|
||||
@@ -2,8 +2,6 @@
|
||||
|
||||
namespace Illuminate\View\Compilers\Concerns;
|
||||
|
||||
use Illuminate\View\Factory as ViewFactory;
|
||||
|
||||
trait CompilesLayouts
|
||||
{
|
||||
/**
|
||||
@@ -23,7 +21,24 @@ trait CompilesLayouts
|
||||
{
|
||||
$expression = $this->stripParentheses($expression);
|
||||
|
||||
$echo = "<?php echo \$__env->make({$expression}, array_except(get_defined_vars(), array('__data', '__path')))->render(); ?>";
|
||||
$echo = "<?php echo \$__env->make({$expression}, \Illuminate\Support\Arr::except(get_defined_vars(), ['__data', '__path']))->render(); ?>";
|
||||
|
||||
$this->footer[] = $echo;
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the extends-first statements into valid PHP.
|
||||
*
|
||||
* @param string $expression
|
||||
* @return string
|
||||
*/
|
||||
protected function compileExtendsFirst($expression)
|
||||
{
|
||||
$expression = $this->stripParentheses($expression);
|
||||
|
||||
$echo = "<?php echo \$__env->first({$expression}, \Illuminate\Support\Arr::except(get_defined_vars(), ['__data', '__path']))->render(); ?>";
|
||||
|
||||
$this->footer[] = $echo;
|
||||
|
||||
@@ -50,7 +65,9 @@ trait CompilesLayouts
|
||||
*/
|
||||
protected function compileParent()
|
||||
{
|
||||
return ViewFactory::parentPlaceholder($this->lastSection ?: '');
|
||||
$escapedLastSection = strtr($this->lastSection, ['\\' => '\\\\', "'" => "\\'"]);
|
||||
|
||||
return "<?php echo \Illuminate\View\Factory::parentPlaceholder('{$escapedLastSection}'); ?>";
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
namespace Illuminate\View\Compilers\Concerns;
|
||||
|
||||
use Illuminate\Contracts\View\ViewCompilationException;
|
||||
|
||||
trait CompilesLoops
|
||||
{
|
||||
/**
|
||||
@@ -16,12 +18,18 @@ trait CompilesLoops
|
||||
*
|
||||
* @param string $expression
|
||||
* @return string
|
||||
*
|
||||
* @throws \Illuminate\Contracts\View\ViewCompilationException
|
||||
*/
|
||||
protected function compileForelse($expression)
|
||||
{
|
||||
$empty = '$__empty_'.++$this->forElseCounter;
|
||||
|
||||
preg_match('/\( *(.*) +as *(.*)\)$/is', $expression, $matches);
|
||||
preg_match('/\( *(.+) +as +(.+)\)$/is', $expression ?? '', $matches);
|
||||
|
||||
if (count($matches) === 0) {
|
||||
throw new ViewCompilationException('Malformed @forelse statement.');
|
||||
}
|
||||
|
||||
$iteratee = trim($matches[1]);
|
||||
|
||||
@@ -87,10 +95,16 @@ trait CompilesLoops
|
||||
*
|
||||
* @param string $expression
|
||||
* @return string
|
||||
*
|
||||
* @throws \Illuminate\Contracts\View\ViewCompilationException
|
||||
*/
|
||||
protected function compileForeach($expression)
|
||||
{
|
||||
preg_match('/\( *(.*) +as *(.*)\)$/is', $expression, $matches);
|
||||
preg_match('/\( *(.+) +as +(.*)\)$/is', $expression ?? '', $matches);
|
||||
|
||||
if (count($matches) === 0) {
|
||||
throw new ViewCompilationException('Malformed @foreach statement.');
|
||||
}
|
||||
|
||||
$iteratee = trim($matches[1]);
|
||||
|
||||
|
||||
@@ -12,17 +12,11 @@ trait CompilesRawPhp
|
||||
*/
|
||||
protected function compilePhp($expression)
|
||||
{
|
||||
return $expression ? "<?php {$expression}; ?>" : '<?php ';
|
||||
}
|
||||
if ($expression) {
|
||||
return "<?php {$expression}; ?>";
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile end-php statements into valid PHP.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function compileEndphp()
|
||||
{
|
||||
return ' ?>';
|
||||
return '@php';
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
namespace Illuminate\View\Compilers\Concerns;
|
||||
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
trait CompilesStacks
|
||||
{
|
||||
/**
|
||||
@@ -26,6 +28,24 @@ trait CompilesStacks
|
||||
return "<?php \$__env->startPush{$expression}; ?>";
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the push-once statements into valid PHP.
|
||||
*
|
||||
* @param string $expression
|
||||
* @return string
|
||||
*/
|
||||
protected function compilePushOnce($expression)
|
||||
{
|
||||
$parts = explode(',', $this->stripParentheses($expression), 2);
|
||||
|
||||
[$stack, $id] = [$parts[0], $parts[1] ?? ''];
|
||||
|
||||
$id = trim($id) ?: "'".(string) Str::uuid()."'";
|
||||
|
||||
return '<?php if (! $__env->hasRenderedOnce('.$id.')): $__env->markAsRenderedOnce('.$id.');
|
||||
$__env->startPush('.$stack.'); ?>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the end-push statements into valid PHP.
|
||||
*
|
||||
@@ -36,6 +56,16 @@ trait CompilesStacks
|
||||
return '<?php $__env->stopPush(); ?>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the end-push-once statements into valid PHP.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function compileEndpushOnce()
|
||||
{
|
||||
return '<?php $__env->stopPush(); endif; ?>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the prepend statements into valid PHP.
|
||||
*
|
||||
@@ -47,6 +77,24 @@ trait CompilesStacks
|
||||
return "<?php \$__env->startPrepend{$expression}; ?>";
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the prepend-once statements into valid PHP.
|
||||
*
|
||||
* @param string $expression
|
||||
* @return string
|
||||
*/
|
||||
protected function compilePrependOnce($expression)
|
||||
{
|
||||
$parts = explode(',', $this->stripParentheses($expression), 2);
|
||||
|
||||
[$stack, $id] = [$parts[0], $parts[1] ?? ''];
|
||||
|
||||
$id = trim($id) ?: "'".(string) Str::uuid()."'";
|
||||
|
||||
return '<?php if (! $__env->hasRenderedOnce('.$id.')): $__env->markAsRenderedOnce('.$id.');
|
||||
$__env->startPrepend('.$stack.'); ?>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the end-prepend statements into valid PHP.
|
||||
*
|
||||
@@ -56,4 +104,14 @@ trait CompilesStacks
|
||||
{
|
||||
return '<?php $__env->stopPrepend(); ?>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the end-prepend-once statements into valid PHP.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function compileEndprependOnce()
|
||||
{
|
||||
return '<?php $__env->stopPrepend(); endif; ?>';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
@@ -16,9 +16,9 @@ trait CompilesTranslations
|
||||
return '<?php $__env->startTranslation(); ?>';
|
||||
} elseif ($expression[1] === '[') {
|
||||
return "<?php \$__env->startTranslation{$expression}; ?>";
|
||||
} else {
|
||||
return "<?php echo app('translator')->getFromJson{$expression}; ?>";
|
||||
}
|
||||
|
||||
return "<?php echo app('translator')->get{$expression}; ?>";
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
458
vendor/laravel/framework/src/Illuminate/View/Component.php
vendored
Normal file
458
vendor/laravel/framework/src/Illuminate/View/Component.php
vendored
Normal file
@@ -0,0 +1,458 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\View;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Container\Container;
|
||||
use Illuminate\Contracts\Support\Htmlable;
|
||||
use Illuminate\Contracts\View\View as ViewContract;
|
||||
use ReflectionClass;
|
||||
use ReflectionMethod;
|
||||
use ReflectionProperty;
|
||||
|
||||
abstract class Component
|
||||
{
|
||||
/**
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* The view factory instance, if any.
|
||||
*
|
||||
* @var \Illuminate\Contracts\View\Factory|null
|
||||
*/
|
||||
protected static $factory;
|
||||
|
||||
/**
|
||||
* The component resolver callback.
|
||||
*
|
||||
* @var (\Closure(string, array): Component)|null
|
||||
*/
|
||||
protected static $componentsResolver;
|
||||
|
||||
/**
|
||||
* The cache of blade view names, keyed by contents.
|
||||
*
|
||||
* @var array<string, string>
|
||||
*/
|
||||
protected static $bladeViewCache = [];
|
||||
|
||||
/**
|
||||
* 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 cache of constructor parameters, keyed by class.
|
||||
*
|
||||
* @var array<class-string, array<int, string>>
|
||||
*/
|
||||
protected static $constructorParametersCache = [];
|
||||
|
||||
/**
|
||||
* Get the view / view contents that represent the component.
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\Support\Htmlable|\Closure|string
|
||||
*/
|
||||
abstract public function render();
|
||||
|
||||
/**
|
||||
* Resolve the component instance with the given data.
|
||||
*
|
||||
* @param array $data
|
||||
* @return static
|
||||
*/
|
||||
public static function resolve($data)
|
||||
{
|
||||
if (static::$componentsResolver) {
|
||||
return call_user_func(static::$componentsResolver, static::class, $data);
|
||||
}
|
||||
|
||||
$parameters = static::extractConstructorParameters();
|
||||
|
||||
$dataKeys = array_keys($data);
|
||||
|
||||
if (empty(array_diff($parameters, $dataKeys))) {
|
||||
return new static(...array_intersect_key($data, array_flip($parameters)));
|
||||
}
|
||||
|
||||
return Container::getInstance()->make(static::class, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract the constructor parameters for the component.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected static function extractConstructorParameters()
|
||||
{
|
||||
if (! isset(static::$constructorParametersCache[static::class])) {
|
||||
$class = new ReflectionClass(static::class);
|
||||
|
||||
$constructor = $class->getConstructor();
|
||||
|
||||
static::$constructorParametersCache[static::class] = $constructor
|
||||
? collect($constructor->getParameters())->map->getName()->all()
|
||||
: [];
|
||||
}
|
||||
|
||||
return static::$constructorParametersCache[static::class];
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve the Blade view or view file that should be used when rendering the component.
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\Support\Htmlable|\Closure|string
|
||||
*/
|
||||
public function resolveView()
|
||||
{
|
||||
$view = $this->render();
|
||||
|
||||
if ($view instanceof ViewContract) {
|
||||
return $view;
|
||||
}
|
||||
|
||||
if ($view instanceof Htmlable) {
|
||||
return $view;
|
||||
}
|
||||
|
||||
$resolver = function ($view) {
|
||||
return $this->extractBladeViewFromString($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 string $contents
|
||||
* @return string
|
||||
*/
|
||||
protected function extractBladeViewFromString($contents)
|
||||
{
|
||||
$key = sprintf('%s::%s', static::class, $contents);
|
||||
|
||||
if (isset(static::$bladeViewCache[$key])) {
|
||||
return static::$bladeViewCache[$key];
|
||||
}
|
||||
|
||||
if (strlen($contents) <= PHP_MAXPATHLEN && $this->factory()->exists($contents)) {
|
||||
return static::$bladeViewCache[$key] = $contents;
|
||||
}
|
||||
|
||||
return static::$bladeViewCache[$key] = $this->createBladeViewFromString($this->factory(), $contents);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 (! is_file($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 ?: $this->newAttributeBag();
|
||||
|
||||
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_starts_with($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 ?: $this->newAttributeBag();
|
||||
|
||||
$this->attributes->setAttributes($attributes);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a new attribute bag instance.
|
||||
*
|
||||
* @param array $attributes
|
||||
* @return \Illuminate\View\ComponentAttributeBag
|
||||
*/
|
||||
protected function newAttributeBag(array $attributes = [])
|
||||
{
|
||||
return new ComponentAttributeBag($attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the component should be rendered.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function shouldRender()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the evaluated view contents for the given view.
|
||||
*
|
||||
* @param string|null $view
|
||||
* @param \Illuminate\Contracts\Support\Arrayable|array $data
|
||||
* @param array $mergeData
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function view($view, $data = [], $mergeData = [])
|
||||
{
|
||||
return $this->factory()->make($view, $data, $mergeData);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the view factory instance.
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\Factory
|
||||
*/
|
||||
protected function factory()
|
||||
{
|
||||
if (is_null(static::$factory)) {
|
||||
static::$factory = Container::getInstance()->make('view');
|
||||
}
|
||||
|
||||
return static::$factory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Flush the component's cached state.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function flushCache()
|
||||
{
|
||||
static::$bladeViewCache = [];
|
||||
static::$constructorParametersCache = [];
|
||||
static::$methodCache = [];
|
||||
static::$propertyCache = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Forget the component's factory instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function forgetFactory()
|
||||
{
|
||||
static::$factory = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Forget the component's resolver callback.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
public static function forgetComponentsResolver()
|
||||
{
|
||||
static::$componentsResolver = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the callback that should be used to resolve components within views.
|
||||
*
|
||||
* @param \Closure(string $component, array $data): Component $resolver
|
||||
* @return void
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
public static function resolveComponentsUsing($resolver)
|
||||
{
|
||||
static::$componentsResolver = $resolver;
|
||||
}
|
||||
}
|
||||
432
vendor/laravel/framework/src/Illuminate/View/ComponentAttributeBag.php
vendored
Normal file
432
vendor/laravel/framework/src/Illuminate/View/ComponentAttributeBag.php
vendored
Normal file
@@ -0,0 +1,432 @@
|
||||
<?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\Conditionable;
|
||||
use Illuminate\Support\Traits\Macroable;
|
||||
use IteratorAggregate;
|
||||
use Traversable;
|
||||
|
||||
class ComponentAttributeBag implements ArrayAccess, Htmlable, IteratorAggregate
|
||||
{
|
||||
use Conditionable, 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if a given attribute exists in the attribute array.
|
||||
*
|
||||
* @param string $key
|
||||
* @return bool
|
||||
*/
|
||||
public function has($key)
|
||||
{
|
||||
return array_key_exists($key, $this->attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if a given attribute is missing from the attribute array.
|
||||
*
|
||||
* @param string $key
|
||||
* @return bool
|
||||
*/
|
||||
public function missing($key)
|
||||
{
|
||||
return ! $this->has($key, $this->attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Only include the given attribute from the attribute array.
|
||||
*
|
||||
* @param mixed $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[] $needles
|
||||
* @return static
|
||||
*/
|
||||
public function whereStartsWith($needles)
|
||||
{
|
||||
return $this->filter(function ($value, $key) use ($needles) {
|
||||
return Str::startsWith($key, $needles);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a bag of attributes with keys that do not start with the given value / pattern.
|
||||
*
|
||||
* @param string|string[] $needles
|
||||
* @return static
|
||||
*/
|
||||
public function whereDoesntStartWith($needles)
|
||||
{
|
||||
return $this->filter(function ($value, $key) use ($needles) {
|
||||
return ! Str::startsWith($key, $needles);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a bag of attributes that have keys starting with the given value / pattern.
|
||||
*
|
||||
* @param string|string[] $needles
|
||||
* @return static
|
||||
*/
|
||||
public function thatStartWith($needles)
|
||||
{
|
||||
return $this->whereStartsWith($needles);
|
||||
}
|
||||
|
||||
/**
|
||||
* Only include the given attribute from the attribute array.
|
||||
*
|
||||
* @param mixed|array $keys
|
||||
* @return static
|
||||
*/
|
||||
public function onlyProps($keys)
|
||||
{
|
||||
return $this->only($this->extractPropNames($keys));
|
||||
}
|
||||
|
||||
/**
|
||||
* Exclude the given attribute from the attribute array.
|
||||
*
|
||||
* @param mixed|array $keys
|
||||
* @return static
|
||||
*/
|
||||
public function exceptProps($keys)
|
||||
{
|
||||
return $this->except($this->extractPropNames($keys));
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract prop names from given keys.
|
||||
*
|
||||
* @param mixed|array $keys
|
||||
* @return array
|
||||
*/
|
||||
protected function extractPropNames($keys)
|
||||
{
|
||||
$props = [];
|
||||
|
||||
foreach ($keys as $key => $defaultValue) {
|
||||
$key = is_numeric($key) ? $defaultValue : $key;
|
||||
|
||||
$props[] = $key;
|
||||
$props[] = Str::kebab($key);
|
||||
}
|
||||
|
||||
return $props;
|
||||
}
|
||||
|
||||
/**
|
||||
* Conditionally merge classes into the attribute bag.
|
||||
*
|
||||
* @param mixed|array $classList
|
||||
* @return static
|
||||
*/
|
||||
public function class($classList)
|
||||
{
|
||||
$classList = Arr::wrap($classList);
|
||||
|
||||
return $this->merge(['class' => Arr::toCssClasses($classList)]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge additional attributes / values into the attribute bag.
|
||||
*
|
||||
* @param array $attributeDefaults
|
||||
* @param bool $escape
|
||||
* @return static
|
||||
*/
|
||||
public function merge(array $attributeDefaults = [], $escape = true)
|
||||
{
|
||||
$attributeDefaults = array_map(function ($value) use ($escape) {
|
||||
return $this->shouldEscapeAttributeValue($escape, $value)
|
||||
? e($value)
|
||||
: $value;
|
||||
}, $attributeDefaults);
|
||||
|
||||
[$appendableAttributes, $nonAppendableAttributes] = collect($this->attributes)
|
||||
->partition(function ($value, $key) use ($attributeDefaults) {
|
||||
return $key === 'class' ||
|
||||
(isset($attributeDefaults[$key]) &&
|
||||
$attributeDefaults[$key] instanceof AppendableAttributeValue);
|
||||
});
|
||||
|
||||
$attributes = $appendableAttributes->mapWithKeys(function ($value, $key) use ($attributeDefaults, $escape) {
|
||||
$defaultsValue = isset($attributeDefaults[$key]) && $attributeDefaults[$key] instanceof AppendableAttributeValue
|
||||
? $this->resolveAppendableAttributeDefault($attributeDefaults, $key, $escape)
|
||||
: ($attributeDefaults[$key] ?? '');
|
||||
|
||||
return [$key => implode(' ', array_unique(array_filter([$defaultsValue, $value])))];
|
||||
})->merge($nonAppendableAttributes)->all();
|
||||
|
||||
return new static(array_merge($attributeDefaults, $attributes));
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the specific attribute value should be escaped.
|
||||
*
|
||||
* @param bool $escape
|
||||
* @param mixed $value
|
||||
* @return bool
|
||||
*/
|
||||
protected function shouldEscapeAttributeValue($escape, $value)
|
||||
{
|
||||
if (! $escape) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return ! is_object($value) &&
|
||||
! is_null($value) &&
|
||||
! is_bool($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new appendable attribute value.
|
||||
*
|
||||
* @param mixed $value
|
||||
* @return \Illuminate\View\AppendableAttributeValue
|
||||
*/
|
||||
public function prepends($value)
|
||||
{
|
||||
return new AppendableAttributeValue($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve an appendable attribute value default value.
|
||||
*
|
||||
* @param array $attributeDefaults
|
||||
* @param string $key
|
||||
* @param bool $escape
|
||||
* @return mixed
|
||||
*/
|
||||
protected function resolveAppendableAttributeDefault($attributeDefaults, $key, $escape)
|
||||
{
|
||||
if ($this->shouldEscapeAttributeValue($escape, $value = $attributeDefaults[$key]->value)) {
|
||||
$value = e($value);
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all of the raw attributes.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getAttributes()
|
||||
{
|
||||
return $this->attributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the underlying attributes.
|
||||
*
|
||||
* @param array $attributes
|
||||
* @return void
|
||||
*/
|
||||
public function setAttributes(array $attributes)
|
||||
{
|
||||
if (isset($attributes['attributes']) &&
|
||||
$attributes['attributes'] instanceof self) {
|
||||
$parentBag = $attributes['attributes'];
|
||||
|
||||
unset($attributes['attributes']);
|
||||
|
||||
$attributes = $parentBag->merge($attributes, $escape = false)->getAttributes();
|
||||
}
|
||||
|
||||
$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): bool
|
||||
{
|
||||
return isset($this->attributes[$offset]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value at the given offset.
|
||||
*
|
||||
* @param string $offset
|
||||
* @return mixed
|
||||
*/
|
||||
public function offsetGet($offset): mixed
|
||||
{
|
||||
return $this->get($offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value at a given offset.
|
||||
*
|
||||
* @param string $offset
|
||||
* @param mixed $value
|
||||
* @return void
|
||||
*/
|
||||
public function offsetSet($offset, $value): void
|
||||
{
|
||||
$this->attributes[$offset] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the value at the given offset.
|
||||
*
|
||||
* @param string $offset
|
||||
* @return void
|
||||
*/
|
||||
public function offsetUnset($offset): void
|
||||
{
|
||||
unset($this->attributes[$offset]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an iterator for the items.
|
||||
*
|
||||
* @return \ArrayIterator
|
||||
*/
|
||||
public function getIterator(): Traversable
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
89
vendor/laravel/framework/src/Illuminate/View/ComponentSlot.php
vendored
Normal file
89
vendor/laravel/framework/src/Illuminate/View/ComponentSlot.php
vendored
Normal file
@@ -0,0 +1,89 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\View;
|
||||
|
||||
use Illuminate\Contracts\Support\Htmlable;
|
||||
|
||||
class ComponentSlot implements Htmlable
|
||||
{
|
||||
/**
|
||||
* The slot attribute bag.
|
||||
*
|
||||
* @var \Illuminate\View\ComponentAttributeBag
|
||||
*/
|
||||
public $attributes;
|
||||
|
||||
/**
|
||||
* The slot contents.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $contents;
|
||||
|
||||
/**
|
||||
* Create a new slot instance.
|
||||
*
|
||||
* @param string $contents
|
||||
* @param array $attributes
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($contents = '', $attributes = [])
|
||||
{
|
||||
$this->contents = $contents;
|
||||
|
||||
$this->withAttributes($attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the extra attributes that the slot should make available.
|
||||
*
|
||||
* @param array $attributes
|
||||
* @return $this
|
||||
*/
|
||||
public function withAttributes(array $attributes)
|
||||
{
|
||||
$this->attributes = new ComponentAttributeBag($attributes);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the slot's HTML string.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function toHtml()
|
||||
{
|
||||
return $this->contents;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the slot is empty.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isEmpty()
|
||||
{
|
||||
return $this->contents === '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the slot is not empty.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isNotEmpty()
|
||||
{
|
||||
return ! $this->isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the slot's HTML string.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return $this->toHtml();
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,11 @@
|
||||
|
||||
namespace Illuminate\View\Concerns;
|
||||
|
||||
use Illuminate\Contracts\Support\Htmlable;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\HtmlString;
|
||||
use Illuminate\View\ComponentSlot;
|
||||
|
||||
trait ManagesComponents
|
||||
{
|
||||
@@ -20,6 +24,13 @@ trait ManagesComponents
|
||||
*/
|
||||
protected $componentData = [];
|
||||
|
||||
/**
|
||||
* The component data for the component that is currently being rendered.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $currentComponentData = [];
|
||||
|
||||
/**
|
||||
* The slot contents for the component.
|
||||
*
|
||||
@@ -37,14 +48,14 @@ trait ManagesComponents
|
||||
/**
|
||||
* Start a component rendering process.
|
||||
*
|
||||
* @param string $name
|
||||
* @param \Illuminate\Contracts\View\View|\Illuminate\Contracts\Support\Htmlable|\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;
|
||||
|
||||
@@ -52,6 +63,22 @@ trait ManagesComponents
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the first view that actually exists from the given list, and start a component.
|
||||
*
|
||||
* @param array $names
|
||||
* @param array $data
|
||||
* @return void
|
||||
*/
|
||||
public function startComponentFirst(array $names, array $data = [])
|
||||
{
|
||||
$name = Arr::first($names, function ($item) {
|
||||
return $this->exists($item);
|
||||
});
|
||||
|
||||
$this->startComponent($name, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the current component.
|
||||
*
|
||||
@@ -59,43 +86,95 @@ trait ManagesComponents
|
||||
*/
|
||||
public function renderComponent()
|
||||
{
|
||||
$name = array_pop($this->componentStack);
|
||||
$view = array_pop($this->componentStack);
|
||||
|
||||
return $this->make($name, $this->componentData($name))->render();
|
||||
$this->currentComponentData = array_merge(
|
||||
$previousComponentData = $this->currentComponentData,
|
||||
$data = $this->componentData()
|
||||
);
|
||||
|
||||
try {
|
||||
$view = value($view, $data);
|
||||
|
||||
if ($view instanceof View) {
|
||||
return $view->with($data)->render();
|
||||
} elseif ($view instanceof Htmlable) {
|
||||
return $view->toHtml();
|
||||
} else {
|
||||
return $this->make($view, $data)->render();
|
||||
}
|
||||
} finally {
|
||||
$this->currentComponentData = $previousComponentData;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the data for the given component.
|
||||
*
|
||||
* @param string $name
|
||||
* @return array
|
||||
*/
|
||||
protected function componentData($name)
|
||||
protected function componentData()
|
||||
{
|
||||
$defaultSlot = new HtmlString(trim(ob_get_clean()));
|
||||
|
||||
$slots = array_merge([
|
||||
'__default' => $defaultSlot,
|
||||
], $this->slots[count($this->componentStack)]);
|
||||
|
||||
return array_merge(
|
||||
$this->componentData[count($this->componentStack)],
|
||||
['slot' => new HtmlString(trim(ob_get_clean()))],
|
||||
$this->slots[count($this->componentStack)]
|
||||
['slot' => $defaultSlot],
|
||||
$this->slots[count($this->componentStack)],
|
||||
['__laravel_slots' => $slots]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an item from the component data that exists above the current component.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $default
|
||||
* @return mixed|null
|
||||
*/
|
||||
public function getConsumableComponentData($key, $default = null)
|
||||
{
|
||||
if (array_key_exists($key, $this->currentComponentData)) {
|
||||
return $this->currentComponentData[$key];
|
||||
}
|
||||
|
||||
$currentComponent = count($this->componentStack);
|
||||
|
||||
if ($currentComponent === 0) {
|
||||
return value($default);
|
||||
}
|
||||
|
||||
for ($i = $currentComponent - 1; $i >= 0; $i--) {
|
||||
$data = $this->componentData[$i] ?? [];
|
||||
|
||||
if (array_key_exists($key, $data)) {
|
||||
return $data[$key];
|
||||
}
|
||||
}
|
||||
|
||||
return value($default);
|
||||
}
|
||||
|
||||
/**
|
||||
* Start the slot rendering process.
|
||||
*
|
||||
* @param string $name
|
||||
* @param string|null $content
|
||||
* @param array $attributes
|
||||
* @return void
|
||||
*/
|
||||
public function slot($name, $content = null)
|
||||
public function slot($name, $content = null, $attributes = [])
|
||||
{
|
||||
if (count(func_get_args()) == 2) {
|
||||
if (func_num_args() === 2 || $content !== null) {
|
||||
$this->slots[$this->currentComponent()][$name] = $content;
|
||||
} else {
|
||||
if (ob_start()) {
|
||||
$this->slots[$this->currentComponent()][$name] = '';
|
||||
} elseif (ob_start()) {
|
||||
$this->slots[$this->currentComponent()][$name] = '';
|
||||
|
||||
$this->slotStack[$this->currentComponent()][] = $name;
|
||||
}
|
||||
$this->slotStack[$this->currentComponent()][] = [$name, $attributes];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -112,8 +191,11 @@ trait ManagesComponents
|
||||
$this->slotStack[$this->currentComponent()]
|
||||
);
|
||||
|
||||
$this->slots[$this->currentComponent()]
|
||||
[$currentSlot] = new HtmlString(trim(ob_get_clean()));
|
||||
[$currentName, $currentAttributes] = $currentSlot;
|
||||
|
||||
$this->slots[$this->currentComponent()][$currentName] = new ComponentSlot(
|
||||
trim(ob_get_clean()), $currentAttributes
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -125,4 +207,16 @@ trait ManagesComponents
|
||||
{
|
||||
return count($this->componentStack) - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Flush all of the component state.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function flushComponents()
|
||||
{
|
||||
$this->componentStack = [];
|
||||
$this->componentData = [];
|
||||
$this->currentComponentData = [];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,15 +3,15 @@
|
||||
namespace Illuminate\View\Concerns;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Contracts\View\View as ViewContract;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
trait ManagesEvents
|
||||
{
|
||||
/**
|
||||
* Register a view creator event.
|
||||
*
|
||||
* @param array|string $views
|
||||
* @param array|string $views
|
||||
* @param \Closure|string $callback
|
||||
* @return array
|
||||
*/
|
||||
@@ -55,7 +55,7 @@ trait ManagesEvents
|
||||
$composers = [];
|
||||
|
||||
foreach ((array) $views as $view) {
|
||||
$composers[] = $this->addViewEvent($view, $callback, 'composing: ');
|
||||
$composers[] = $this->addViewEvent($view, $callback);
|
||||
}
|
||||
|
||||
return $composers;
|
||||
@@ -85,9 +85,9 @@ trait ManagesEvents
|
||||
/**
|
||||
* Register a class based view composer.
|
||||
*
|
||||
* @param string $view
|
||||
* @param string $class
|
||||
* @param string $prefix
|
||||
* @param string $view
|
||||
* @param string $class
|
||||
* @param string $prefix
|
||||
* @return \Closure
|
||||
*/
|
||||
protected function addClassEvent($view, $class, $prefix)
|
||||
@@ -115,15 +115,13 @@ trait ManagesEvents
|
||||
*/
|
||||
protected function buildClassEventCallback($class, $prefix)
|
||||
{
|
||||
list($class, $method) = $this->parseClassEvent($class, $prefix);
|
||||
[$class, $method] = $this->parseClassEvent($class, $prefix);
|
||||
|
||||
// Once we have the class and method name, we can build the Closure to resolve
|
||||
// the instance out of the IoC container and call the method on it with the
|
||||
// given arguments that are passed to the Closure as the composer's data.
|
||||
return function () use ($class, $method) {
|
||||
return call_user_func_array(
|
||||
[$this->container->make($class), $method], func_get_args()
|
||||
);
|
||||
return $this->container->make($class)->{$method}(...func_get_args());
|
||||
};
|
||||
}
|
||||
|
||||
@@ -147,19 +145,19 @@ trait ManagesEvents
|
||||
*/
|
||||
protected function classEventMethodForPrefix($prefix)
|
||||
{
|
||||
return Str::contains($prefix, 'composing') ? 'compose' : 'create';
|
||||
return str_contains($prefix, 'composing') ? 'compose' : 'create';
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a listener to the event dispatcher.
|
||||
*
|
||||
* @param string $name
|
||||
* @param string $name
|
||||
* @param \Closure $callback
|
||||
* @return void
|
||||
*/
|
||||
protected function addEventListener($name, $callback)
|
||||
{
|
||||
if (Str::contains($name, '*')) {
|
||||
if (str_contains($name, '*')) {
|
||||
$callback = function ($name, array $data) use ($callback) {
|
||||
return $callback($data[0]);
|
||||
};
|
||||
@@ -176,7 +174,7 @@ trait ManagesEvents
|
||||
*/
|
||||
public function callComposer(ViewContract $view)
|
||||
{
|
||||
$this->events->fire('composing: '.$view->name(), [$view]);
|
||||
$this->events->dispatch('composing: '.$view->name(), [$view]);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -187,6 +185,6 @@ trait ManagesEvents
|
||||
*/
|
||||
public function callCreator(ViewContract $view)
|
||||
{
|
||||
$this->events->fire('creating: '.$view->name(), [$view]);
|
||||
$this->events->dispatch('creating: '.$view->name(), [$view]);
|
||||
}
|
||||
}
|
||||
|
||||
88
vendor/laravel/framework/src/Illuminate/View/Concerns/ManagesFragments.php
vendored
Normal file
88
vendor/laravel/framework/src/Illuminate/View/Concerns/ManagesFragments.php
vendored
Normal file
@@ -0,0 +1,88 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\View\Concerns;
|
||||
|
||||
use InvalidArgumentException;
|
||||
|
||||
trait ManagesFragments
|
||||
{
|
||||
/**
|
||||
* All of the captured, rendered fragments.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $fragments = [];
|
||||
|
||||
/**
|
||||
* The stack of in-progress fragment renders.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $fragmentStack = [];
|
||||
|
||||
/**
|
||||
* Start injecting content into a fragment.
|
||||
*
|
||||
* @param string $fragment
|
||||
* @return void
|
||||
*/
|
||||
public function startFragment($fragment)
|
||||
{
|
||||
if (ob_start()) {
|
||||
$this->fragmentStack[] = $fragment;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop injecting content into a fragment.
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function stopFragment()
|
||||
{
|
||||
if (empty($this->fragmentStack)) {
|
||||
throw new InvalidArgumentException('Cannot end a fragment without first starting one.');
|
||||
}
|
||||
|
||||
$last = array_pop($this->fragmentStack);
|
||||
|
||||
$this->fragments[$last] = ob_get_clean();
|
||||
|
||||
return $this->fragments[$last];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the contents of a fragment.
|
||||
*
|
||||
* @param string $name
|
||||
* @param string|null $default
|
||||
* @return mixed
|
||||
*/
|
||||
public function getFragment($name, $default = null)
|
||||
{
|
||||
return $this->getFragments()[$name] ?? $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the entire array of rendered fragments.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getFragments()
|
||||
{
|
||||
return $this->fragments;
|
||||
}
|
||||
|
||||
/**
|
||||
* Flush all of the fragments.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function flushFragments()
|
||||
{
|
||||
$this->fragments = [];
|
||||
$this->fragmentStack = [];
|
||||
}
|
||||
}
|
||||
@@ -2,8 +2,9 @@
|
||||
|
||||
namespace Illuminate\View\Concerns;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Support\Str;
|
||||
use InvalidArgumentException;
|
||||
|
||||
trait ManagesLayouts
|
||||
{
|
||||
@@ -24,10 +25,17 @@ trait ManagesLayouts
|
||||
/**
|
||||
* The parent placeholder for the request.
|
||||
*
|
||||
* @var string
|
||||
* @var mixed
|
||||
*/
|
||||
protected static $parentPlaceholder = [];
|
||||
|
||||
/**
|
||||
* The parent placeholder salt for the request.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected static $parentPlaceholderSalt;
|
||||
|
||||
/**
|
||||
* Start injecting content into a section.
|
||||
*
|
||||
@@ -55,7 +63,7 @@ trait ManagesLayouts
|
||||
*/
|
||||
public function inject($section, $content)
|
||||
{
|
||||
return $this->startSection($section, $content);
|
||||
$this->startSection($section, $content);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -77,6 +85,7 @@ trait ManagesLayouts
|
||||
*
|
||||
* @param bool $overwrite
|
||||
* @return string
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function stopSection($overwrite = false)
|
||||
@@ -100,6 +109,7 @@ trait ManagesLayouts
|
||||
* Stop injecting content into a section and append it.
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function appendSection()
|
||||
@@ -166,12 +176,28 @@ trait ManagesLayouts
|
||||
public static function parentPlaceholder($section = '')
|
||||
{
|
||||
if (! isset(static::$parentPlaceholder[$section])) {
|
||||
static::$parentPlaceholder[$section] = '##parent-placeholder-'.sha1($section).'##';
|
||||
$salt = static::parentPlaceholderSalt();
|
||||
|
||||
static::$parentPlaceholder[$section] = '##parent-placeholder-'.sha1($salt.$section).'##';
|
||||
}
|
||||
|
||||
return static::$parentPlaceholder[$section];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the parent placeholder salt.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected static function parentPlaceholderSalt()
|
||||
{
|
||||
if (! static::$parentPlaceholderSalt) {
|
||||
return static::$parentPlaceholderSalt = Str::random(40);
|
||||
}
|
||||
|
||||
return static::$parentPlaceholderSalt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if section exists.
|
||||
*
|
||||
@@ -183,16 +209,27 @@ 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.
|
||||
*
|
||||
* @param string $name
|
||||
* @param string $default
|
||||
* @param string|null $default
|
||||
* @return mixed
|
||||
*/
|
||||
public function getSection($name, $default = null)
|
||||
{
|
||||
return isset($this->getSections()[$name]) ? $this->getSections()[$name] : $default;
|
||||
return $this->getSections()[$name] ?? $default;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
namespace Illuminate\View\Concerns;
|
||||
|
||||
use Countable;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\LazyCollection;
|
||||
|
||||
trait ManagesLoops
|
||||
{
|
||||
@@ -22,17 +22,21 @@ trait ManagesLoops
|
||||
*/
|
||||
public function addLoop($data)
|
||||
{
|
||||
$length = is_array($data) || $data instanceof Countable ? count($data) : null;
|
||||
$length = is_countable($data) && ! $data instanceof LazyCollection
|
||||
? count($data)
|
||||
: null;
|
||||
|
||||
$parent = Arr::last($this->loopsStack);
|
||||
|
||||
$this->loopsStack[] = [
|
||||
'iteration' => 0,
|
||||
'index' => 0,
|
||||
'remaining' => isset($length) ? $length : null,
|
||||
'remaining' => $length ?? null,
|
||||
'count' => $length,
|
||||
'first' => true,
|
||||
'last' => isset($length) ? $length == 1 : null,
|
||||
'odd' => false,
|
||||
'even' => true,
|
||||
'depth' => count($this->loopsStack) + 1,
|
||||
'parent' => $parent ? (object) $parent : null,
|
||||
];
|
||||
@@ -51,6 +55,8 @@ trait ManagesLoops
|
||||
'iteration' => $loop['iteration'] + 1,
|
||||
'index' => $loop['iteration'],
|
||||
'first' => $loop['iteration'] == 0,
|
||||
'odd' => ! $loop['odd'],
|
||||
'even' => ! $loop['even'],
|
||||
'remaining' => isset($loop['count']) ? $loop['remaining'] - 1 : null,
|
||||
'last' => isset($loop['count']) ? $loop['iteration'] == $loop['count'] - 1 : null,
|
||||
]);
|
||||
|
||||
@@ -49,6 +49,7 @@ trait ManagesStacks
|
||||
* Stop injecting content into a push section.
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function stopPush()
|
||||
@@ -104,6 +105,7 @@ trait ManagesStacks
|
||||
* Stop prepending content into a push section.
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function stopPrepend()
|
||||
|
||||
@@ -31,7 +31,7 @@ trait ManagesTranslations
|
||||
*/
|
||||
public function renderTranslation()
|
||||
{
|
||||
return $this->container->make('translator')->getFromJson(
|
||||
return $this->container->make('translator')->get(
|
||||
trim(ob_get_clean()), $this->translationReplacements
|
||||
);
|
||||
}
|
||||
|
||||
172
vendor/laravel/framework/src/Illuminate/View/DynamicComponent.php
vendored
Normal file
172
vendor/laravel/framework/src/Illuminate/View/DynamicComponent.php
vendored
Normal file
@@ -0,0 +1,172 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\View;
|
||||
|
||||
use Illuminate\Container\Container;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\View\Compilers\ComponentTagCompiler;
|
||||
|
||||
class DynamicComponent extends Component
|
||||
{
|
||||
/**
|
||||
* The name of the component.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $component;
|
||||
|
||||
/**
|
||||
* The component tag compiler instance.
|
||||
*
|
||||
* @var \Illuminate\View\Compilers\BladeTagCompiler
|
||||
*/
|
||||
protected static $compiler;
|
||||
|
||||
/**
|
||||
* The cached component classes.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected static $componentClasses = [];
|
||||
|
||||
/**
|
||||
* Create a new component instance.
|
||||
*
|
||||
* @param string $component
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(string $component)
|
||||
{
|
||||
$this->component = $component;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the view / contents that represent the component.
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View|string
|
||||
*/
|
||||
public function render()
|
||||
{
|
||||
$template = <<<'EOF'
|
||||
<?php extract(collect($attributes->getAttributes())->mapWithKeys(function ($value, $key) { return [Illuminate\Support\Str::camel(str_replace([':', '.'], ' ', $key)) => $value]; })->all(), EXTR_SKIP); ?>
|
||||
{{ props }}
|
||||
<x-{{ component }} {{ bindings }} {{ attributes }}>
|
||||
{{ slots }}
|
||||
{{ defaultSlot }}
|
||||
</x-{{ component }}>
|
||||
EOF;
|
||||
|
||||
return function ($data) use ($template) {
|
||||
$bindings = $this->bindings($class = $this->classForComponent());
|
||||
|
||||
return str_replace(
|
||||
[
|
||||
'{{ component }}',
|
||||
'{{ props }}',
|
||||
'{{ bindings }}',
|
||||
'{{ attributes }}',
|
||||
'{{ slots }}',
|
||||
'{{ defaultSlot }}',
|
||||
],
|
||||
[
|
||||
$this->component,
|
||||
$this->compileProps($bindings),
|
||||
$this->compileBindings($bindings),
|
||||
class_exists($class) ? '{{ $attributes }}' : '',
|
||||
$this->compileSlots($data['__laravel_slots']),
|
||||
'{{ $slot ?? "" }}',
|
||||
],
|
||||
$template
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the @props directive for the component.
|
||||
*
|
||||
* @param array $bindings
|
||||
* @return string
|
||||
*/
|
||||
protected function compileProps(array $bindings)
|
||||
{
|
||||
if (empty($bindings)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return '@props('.'[\''.implode('\',\'', collect($bindings)->map(function ($dataKey) {
|
||||
return Str::camel($dataKey);
|
||||
})->all()).'\']'.')';
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the bindings for the component.
|
||||
*
|
||||
* @param array $bindings
|
||||
* @return string
|
||||
*/
|
||||
protected function compileBindings(array $bindings)
|
||||
{
|
||||
return collect($bindings)->map(function ($key) {
|
||||
return ':'.$key.'="$'.Str::camel(str_replace([':', '.'], ' ', $key)).'"';
|
||||
})->implode(' ');
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the slots for the component.
|
||||
*
|
||||
* @param array $slots
|
||||
* @return string
|
||||
*/
|
||||
protected function compileSlots(array $slots)
|
||||
{
|
||||
return collect($slots)->map(function ($slot, $name) {
|
||||
return $name === '__default' ? null : '<x-slot name="'.$name.'" '.((string) $slot->attributes).'>{{ $'.$name.' }}</x-slot>';
|
||||
})->filter()->implode(PHP_EOL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the class for the current component.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function classForComponent()
|
||||
{
|
||||
if (isset(static::$componentClasses[$this->component])) {
|
||||
return static::$componentClasses[$this->component];
|
||||
}
|
||||
|
||||
return static::$componentClasses[$this->component] =
|
||||
$this->compiler()->componentClass($this->component);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the names of the variables that should be bound to the component.
|
||||
*
|
||||
* @param string $class
|
||||
* @return array
|
||||
*/
|
||||
protected function bindings(string $class)
|
||||
{
|
||||
[$data, $attributes] = $this->compiler()->partitionDataAndAttributes($class, $this->attributes->getAttributes());
|
||||
|
||||
return array_keys($data->all());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an instance of the Blade tag compiler.
|
||||
*
|
||||
* @return \Illuminate\View\Compilers\ComponentTagCompiler
|
||||
*/
|
||||
protected function compiler()
|
||||
{
|
||||
if (! static::$compiler) {
|
||||
static::$compiler = new ComponentTagCompiler(
|
||||
Container::getInstance()->make('blade.compiler')->getClassComponentAliases(),
|
||||
Container::getInstance()->make('blade.compiler')->getClassComponentNamespaces(),
|
||||
Container::getInstance()->make('blade.compiler')
|
||||
);
|
||||
}
|
||||
|
||||
return static::$compiler;
|
||||
}
|
||||
}
|
||||
@@ -2,9 +2,10 @@
|
||||
|
||||
namespace Illuminate\View\Engines;
|
||||
|
||||
use Exception;
|
||||
use ErrorException;
|
||||
use Illuminate\Filesystem\Filesystem;
|
||||
use Illuminate\View\Compilers\CompilerInterface;
|
||||
use Illuminate\View\ViewException;
|
||||
use Throwable;
|
||||
|
||||
class CompilerEngine extends PhpEngine
|
||||
{
|
||||
@@ -23,13 +24,23 @@ class CompilerEngine extends PhpEngine
|
||||
protected $lastCompiled = [];
|
||||
|
||||
/**
|
||||
* Create a new Blade view engine instance.
|
||||
* The view paths that were compiled or are not expired, keyed by the path.
|
||||
*
|
||||
* @var array<string, true>
|
||||
*/
|
||||
protected $compiledOrNotExpired = [];
|
||||
|
||||
/**
|
||||
* Create a new compiler engine instance.
|
||||
*
|
||||
* @param \Illuminate\View\Compilers\CompilerInterface $compiler
|
||||
* @param \Illuminate\Filesystem\Filesystem|null $files
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(CompilerInterface $compiler)
|
||||
public function __construct(CompilerInterface $compiler, Filesystem $files = null)
|
||||
{
|
||||
parent::__construct($files ?: new Filesystem);
|
||||
|
||||
$this->compiler = $compiler;
|
||||
}
|
||||
|
||||
@@ -37,7 +48,7 @@ class CompilerEngine extends PhpEngine
|
||||
* Get the evaluated contents of the view.
|
||||
*
|
||||
* @param string $path
|
||||
* @param array $data
|
||||
* @param array $data
|
||||
* @return string
|
||||
*/
|
||||
public function get($path, array $data = [])
|
||||
@@ -47,16 +58,31 @@ class CompilerEngine extends PhpEngine
|
||||
// If this given view has expired, which means it has simply been edited since
|
||||
// it was last compiled, we will re-compile the views so we can evaluate a
|
||||
// fresh copy of the view. We'll pass the compiler the path of the view.
|
||||
if ($this->compiler->isExpired($path)) {
|
||||
if (! isset($this->compiledOrNotExpired[$path]) && $this->compiler->isExpired($path)) {
|
||||
$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);
|
||||
|
||||
try {
|
||||
$results = $this->evaluatePath($this->compiler->getCompiledPath($path), $data);
|
||||
} catch (ViewException $e) {
|
||||
if (! str($e->getMessage())->contains(['No such file or directory', 'File does not exist at path'])) {
|
||||
throw $e;
|
||||
}
|
||||
|
||||
if (! isset($this->compiledOrNotExpired[$path])) {
|
||||
throw $e;
|
||||
}
|
||||
|
||||
$this->compiler->compile($path);
|
||||
|
||||
$results = $this->evaluatePath($this->compiler->getCompiledPath($path), $data);
|
||||
}
|
||||
|
||||
$this->compiledOrNotExpired[$path] = true;
|
||||
|
||||
array_pop($this->lastCompiled);
|
||||
|
||||
@@ -66,15 +92,15 @@ 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 ErrorException($this->getMessage($e), 0, 1, $e->getFile(), $e->getLine(), $e);
|
||||
$e = new ViewException($this->getMessage($e), 0, 1, $e->getFile(), $e->getLine(), $e);
|
||||
|
||||
parent::handleViewException($e, $obLevel);
|
||||
}
|
||||
@@ -82,10 +108,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)).')';
|
||||
}
|
||||
@@ -99,4 +125,14 @@ class CompilerEngine extends PhpEngine
|
||||
{
|
||||
return $this->compiler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the cache of views that were compiled or not expired.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function forgetCompiledOrNotExpired()
|
||||
{
|
||||
$this->compiledOrNotExpired = [];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\View\Engines;
|
||||
|
||||
interface EngineInterface
|
||||
{
|
||||
/**
|
||||
* Get the evaluated contents of the view.
|
||||
*
|
||||
* @param string $path
|
||||
* @param array $data
|
||||
* @return string
|
||||
*/
|
||||
public function get($path, array $data = []);
|
||||
}
|
||||
@@ -26,22 +26,23 @@ class EngineResolver
|
||||
*
|
||||
* The engine string typically corresponds to a file extension.
|
||||
*
|
||||
* @param string $engine
|
||||
* @param string $engine
|
||||
* @param \Closure $resolver
|
||||
* @return void
|
||||
*/
|
||||
public function register($engine, Closure $resolver)
|
||||
{
|
||||
unset($this->resolved[$engine]);
|
||||
$this->forget($engine);
|
||||
|
||||
$this->resolvers[$engine] = $resolver;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolver an engine instance by name.
|
||||
* Resolve an engine instance by name.
|
||||
*
|
||||
* @param string $engine
|
||||
* @return \Illuminate\View\Engines\EngineInterface
|
||||
* @return \Illuminate\Contracts\View\Engine
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function resolve($engine)
|
||||
@@ -54,6 +55,17 @@ class EngineResolver
|
||||
return $this->resolved[$engine] = call_user_func($this->resolvers[$engine]);
|
||||
}
|
||||
|
||||
throw new InvalidArgumentException("Engine $engine not found.");
|
||||
throw new InvalidArgumentException("Engine [{$engine}] not found.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a resolved engine.
|
||||
*
|
||||
* @param string $engine
|
||||
* @return void
|
||||
*/
|
||||
public function forget($engine)
|
||||
{
|
||||
unset($this->resolved[$engine]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,17 +2,38 @@
|
||||
|
||||
namespace Illuminate\View\Engines;
|
||||
|
||||
class FileEngine implements EngineInterface
|
||||
use Illuminate\Contracts\View\Engine;
|
||||
use Illuminate\Filesystem\Filesystem;
|
||||
|
||||
class FileEngine implements Engine
|
||||
{
|
||||
/**
|
||||
* The filesystem instance.
|
||||
*
|
||||
* @var \Illuminate\Filesystem\Filesystem
|
||||
*/
|
||||
protected $files;
|
||||
|
||||
/**
|
||||
* Create a new file engine instance.
|
||||
*
|
||||
* @param \Illuminate\Filesystem\Filesystem $files
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Filesystem $files)
|
||||
{
|
||||
$this->files = $files;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the evaluated contents of the view.
|
||||
*
|
||||
* @param string $path
|
||||
* @param array $data
|
||||
* @param array $data
|
||||
* @return string
|
||||
*/
|
||||
public function get($path, array $data = [])
|
||||
{
|
||||
return file_get_contents($path);
|
||||
return $this->files->get($path);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,17 +2,35 @@
|
||||
|
||||
namespace Illuminate\View\Engines;
|
||||
|
||||
use Exception;
|
||||
use Illuminate\Contracts\View\Engine;
|
||||
use Illuminate\Filesystem\Filesystem;
|
||||
use Throwable;
|
||||
use Symfony\Component\Debug\Exception\FatalThrowableError;
|
||||
|
||||
class PhpEngine implements EngineInterface
|
||||
class PhpEngine implements Engine
|
||||
{
|
||||
/**
|
||||
* The filesystem instance.
|
||||
*
|
||||
* @var \Illuminate\Filesystem\Filesystem
|
||||
*/
|
||||
protected $files;
|
||||
|
||||
/**
|
||||
* Create a new file engine instance.
|
||||
*
|
||||
* @param \Illuminate\Filesystem\Filesystem $files
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Filesystem $files)
|
||||
{
|
||||
$this->files = $files;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the evaluated contents of the view.
|
||||
*
|
||||
* @param string $path
|
||||
* @param array $data
|
||||
* @param array $data
|
||||
* @return string
|
||||
*/
|
||||
public function get($path, array $data = [])
|
||||
@@ -23,27 +41,23 @@ class PhpEngine implements EngineInterface
|
||||
/**
|
||||
* Get the evaluated contents of the view at the given path.
|
||||
*
|
||||
* @param string $__path
|
||||
* @param array $__data
|
||||
* @param string $path
|
||||
* @param array $data
|
||||
* @return string
|
||||
*/
|
||||
protected function evaluatePath($__path, $__data)
|
||||
protected function evaluatePath($path, $data)
|
||||
{
|
||||
$obLevel = ob_get_level();
|
||||
|
||||
ob_start();
|
||||
|
||||
extract($__data, EXTR_SKIP);
|
||||
|
||||
// We'll evaluate the contents of the view inside a try/catch block so we can
|
||||
// flush out any stray output that might get out before an error occurs or
|
||||
// an exception is thrown. This prevents any partial views from leaking.
|
||||
try {
|
||||
include $__path;
|
||||
} catch (Exception $e) {
|
||||
$this->handleViewException($e, $obLevel);
|
||||
$this->files->getRequire($path, $data);
|
||||
} catch (Throwable $e) {
|
||||
$this->handleViewException(new FatalThrowableError($e), $obLevel);
|
||||
$this->handleViewException($e, $obLevel);
|
||||
}
|
||||
|
||||
return ltrim(ob_get_clean());
|
||||
@@ -52,13 +66,13 @@ class PhpEngine implements EngineInterface
|
||||
/**
|
||||
* 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();
|
||||
|
||||
@@ -2,19 +2,21 @@
|
||||
|
||||
namespace Illuminate\View;
|
||||
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Str;
|
||||
use InvalidArgumentException;
|
||||
use Illuminate\Contracts\Container\Container;
|
||||
use Illuminate\Contracts\Events\Dispatcher;
|
||||
use Illuminate\Contracts\Support\Arrayable;
|
||||
use Illuminate\View\Engines\EngineResolver;
|
||||
use Illuminate\Contracts\Container\Container;
|
||||
use Illuminate\Contracts\View\Factory as FactoryContract;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Traits\Macroable;
|
||||
use Illuminate\View\Engines\EngineResolver;
|
||||
use InvalidArgumentException;
|
||||
|
||||
class Factory implements FactoryContract
|
||||
{
|
||||
use Concerns\ManagesComponents,
|
||||
use Macroable,
|
||||
Concerns\ManagesComponents,
|
||||
Concerns\ManagesEvents,
|
||||
Concerns\ManagesFragments,
|
||||
Concerns\ManagesLayouts,
|
||||
Concerns\ManagesLoops,
|
||||
Concerns\ManagesStacks,
|
||||
@@ -64,6 +66,7 @@ class Factory implements FactoryContract
|
||||
'blade.php' => 'blade',
|
||||
'php' => 'php',
|
||||
'css' => 'file',
|
||||
'html' => 'file',
|
||||
];
|
||||
|
||||
/**
|
||||
@@ -80,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.
|
||||
*
|
||||
@@ -101,8 +111,8 @@ class Factory implements FactoryContract
|
||||
* Get the evaluated view contents for the given view.
|
||||
*
|
||||
* @param string $path
|
||||
* @param array $data
|
||||
* @param array $mergeData
|
||||
* @param \Illuminate\Contracts\Support\Arrayable|array $data
|
||||
* @param array $mergeData
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function file($path, $data = [], $mergeData = [])
|
||||
@@ -118,8 +128,8 @@ class Factory implements FactoryContract
|
||||
* Get the evaluated view contents for the given view.
|
||||
*
|
||||
* @param string $view
|
||||
* @param array $data
|
||||
* @param array $mergeData
|
||||
* @param \Illuminate\Contracts\Support\Arrayable|array $data
|
||||
* @param array $mergeData
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function make($view, $data = [], $mergeData = [])
|
||||
@@ -138,13 +148,36 @@ class Factory implements FactoryContract
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the first view that actually exists from the given list.
|
||||
*
|
||||
* @param array $views
|
||||
* @param \Illuminate\Contracts\Support\Arrayable|array $data
|
||||
* @param array $mergeData
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function first(array $views, $data = [], $mergeData = [])
|
||||
{
|
||||
$view = Arr::first($views, function ($view) {
|
||||
return $this->exists($view);
|
||||
});
|
||||
|
||||
if (! $view) {
|
||||
throw new InvalidArgumentException('None of the views in the given array exist.');
|
||||
}
|
||||
|
||||
return $this->make($view, $data, $mergeData);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rendered content of the view based on a given condition.
|
||||
*
|
||||
* @param bool $condition
|
||||
* @param string $view
|
||||
* @param array $data
|
||||
* @param array $mergeData
|
||||
* @param \Illuminate\Contracts\Support\Arrayable|array $data
|
||||
* @param array $mergeData
|
||||
* @return string
|
||||
*/
|
||||
public function renderWhen($condition, $view, $data = [], $mergeData = [])
|
||||
@@ -156,11 +189,25 @@ class Factory implements FactoryContract
|
||||
return $this->make($view, $this->parseData($data), $mergeData)->render();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rendered content of the view based on the negation of a given condition.
|
||||
*
|
||||
* @param bool $condition
|
||||
* @param string $view
|
||||
* @param \Illuminate\Contracts\Support\Arrayable|array $data
|
||||
* @param array $mergeData
|
||||
* @return string
|
||||
*/
|
||||
public function renderUnless($condition, $view, $data = [], $mergeData = [])
|
||||
{
|
||||
return $this->renderWhen(! $condition, $view, $data, $mergeData);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rendered contents of a partial from a loop.
|
||||
*
|
||||
* @param string $view
|
||||
* @param array $data
|
||||
* @param array $data
|
||||
* @param string $iterator
|
||||
* @param string $empty
|
||||
* @return string
|
||||
@@ -184,7 +231,7 @@ class Factory implements FactoryContract
|
||||
// view. Alternatively, the "empty view" could be a raw string that begins
|
||||
// with "raw|" for convenience and to let this know that it is a string.
|
||||
else {
|
||||
$result = Str::startsWith($empty, 'raw|')
|
||||
$result = str_starts_with($empty, 'raw|')
|
||||
? substr($empty, 4)
|
||||
: $this->make($empty)->render();
|
||||
}
|
||||
@@ -195,7 +242,7 @@ class Factory implements FactoryContract
|
||||
/**
|
||||
* Normalize a view name.
|
||||
*
|
||||
* @param string $name
|
||||
* @param string $name
|
||||
* @return string
|
||||
*/
|
||||
protected function normalizeName($name)
|
||||
@@ -219,7 +266,7 @@ class Factory implements FactoryContract
|
||||
*
|
||||
* @param string $view
|
||||
* @param string $path
|
||||
* @param array $data
|
||||
* @param \Illuminate\Contracts\Support\Arrayable|array $data
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
protected function viewInstance($view, $path, $data)
|
||||
@@ -248,14 +295,14 @@ class Factory implements FactoryContract
|
||||
* Get the appropriate view engine for the given path.
|
||||
*
|
||||
* @param string $path
|
||||
* @return \Illuminate\View\Engines\EngineInterface
|
||||
* @return \Illuminate\Contracts\View\Engine
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
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];
|
||||
@@ -267,14 +314,14 @@ class Factory implements FactoryContract
|
||||
* Get the extension used by the view file.
|
||||
*
|
||||
* @param string $path
|
||||
* @return string
|
||||
* @return string|null
|
||||
*/
|
||||
protected function getExtension($path)
|
||||
{
|
||||
$extensions = array_keys($this->extensions);
|
||||
|
||||
return Arr::first($extensions, function ($value) use ($path) {
|
||||
return Str::endsWith($path, '.'.$value);
|
||||
return str_ends_with($path, '.'.$value);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -282,7 +329,7 @@ class Factory implements FactoryContract
|
||||
* Add a piece of shared data to the environment.
|
||||
*
|
||||
* @param array|string $key
|
||||
* @param mixed $value
|
||||
* @param mixed|null $value
|
||||
* @return mixed
|
||||
*/
|
||||
public function share($key, $value = null)
|
||||
@@ -326,6 +373,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.
|
||||
*
|
||||
@@ -382,9 +451,9 @@ class Factory implements FactoryContract
|
||||
/**
|
||||
* Register a valid view extension and its engine.
|
||||
*
|
||||
* @param string $extension
|
||||
* @param string $engine
|
||||
* @param \Closure $resolver
|
||||
* @param string $extension
|
||||
* @param string $engine
|
||||
* @param \Closure|null $resolver
|
||||
* @return void
|
||||
*/
|
||||
public function addExtension($extension, $engine, $resolver = null)
|
||||
@@ -408,9 +477,12 @@ class Factory implements FactoryContract
|
||||
public function flushState()
|
||||
{
|
||||
$this->renderCount = 0;
|
||||
$this->renderedOnce = [];
|
||||
|
||||
$this->flushSections();
|
||||
$this->flushStacks();
|
||||
$this->flushComponents();
|
||||
$this->flushFragments();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -522,7 +594,7 @@ class Factory implements FactoryContract
|
||||
* Get an item from the shared data.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $default
|
||||
* @param mixed $default
|
||||
* @return mixed
|
||||
*/
|
||||
public function shared($key, $default = null)
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
namespace Illuminate\View;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use Illuminate\Filesystem\Filesystem;
|
||||
use InvalidArgumentException;
|
||||
|
||||
class FileViewFinder implements ViewFinderInterface
|
||||
{
|
||||
@@ -38,22 +38,22 @@ class FileViewFinder implements ViewFinderInterface
|
||||
/**
|
||||
* Register a view extension with the finder.
|
||||
*
|
||||
* @var array
|
||||
* @var string[]
|
||||
*/
|
||||
protected $extensions = ['blade.php', 'php', 'css'];
|
||||
protected $extensions = ['blade.php', 'php', 'css', 'html'];
|
||||
|
||||
/**
|
||||
* Create a new file view loader instance.
|
||||
*
|
||||
* @param \Illuminate\Filesystem\Filesystem $files
|
||||
* @param array $paths
|
||||
* @param array $extensions
|
||||
* @param array|null $extensions
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Filesystem $files, array $paths, array $extensions = null)
|
||||
{
|
||||
$this->files = $files;
|
||||
$this->paths = $paths;
|
||||
$this->paths = array_map([$this, 'resolvePath'], $paths);
|
||||
|
||||
if (isset($extensions)) {
|
||||
$this->extensions = $extensions;
|
||||
@@ -87,7 +87,7 @@ class FileViewFinder implements ViewFinderInterface
|
||||
*/
|
||||
protected function findNamespacedView($name)
|
||||
{
|
||||
list($namespace, $view) = $this->parseNamespaceSegments($name);
|
||||
[$namespace, $view] = $this->parseNamespaceSegments($name);
|
||||
|
||||
return $this->findInPaths($view, $this->hints[$namespace]);
|
||||
}
|
||||
@@ -104,8 +104,8 @@ class FileViewFinder implements ViewFinderInterface
|
||||
{
|
||||
$segments = explode(static::HINT_PATH_DELIMITER, $name);
|
||||
|
||||
if (count($segments) != 2) {
|
||||
throw new InvalidArgumentException("View [$name] has an invalid name.");
|
||||
if (count($segments) !== 2) {
|
||||
throw new InvalidArgumentException("View [{$name}] has an invalid name.");
|
||||
}
|
||||
|
||||
if (! isset($this->hints[$segments[0]])) {
|
||||
@@ -119,7 +119,7 @@ class FileViewFinder implements ViewFinderInterface
|
||||
* Find the given view in the list of paths.
|
||||
*
|
||||
* @param string $name
|
||||
* @param array $paths
|
||||
* @param array $paths
|
||||
* @return string
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
@@ -134,7 +134,7 @@ class FileViewFinder implements ViewFinderInterface
|
||||
}
|
||||
}
|
||||
|
||||
throw new InvalidArgumentException("View [$name] not found.");
|
||||
throw new InvalidArgumentException("View [{$name}] not found.");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -145,9 +145,7 @@ class FileViewFinder implements ViewFinderInterface
|
||||
*/
|
||||
protected function getPossibleViewFiles($name)
|
||||
{
|
||||
return array_map(function ($extension) use ($name) {
|
||||
return str_replace('.', '/', $name).'.'.$extension;
|
||||
}, $this->extensions);
|
||||
return array_map(fn ($extension) => str_replace('.', '/', $name).'.'.$extension, $this->extensions);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -158,7 +156,7 @@ class FileViewFinder implements ViewFinderInterface
|
||||
*/
|
||||
public function addLocation($location)
|
||||
{
|
||||
$this->paths[] = $location;
|
||||
$this->paths[] = $this->resolvePath($location);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -169,7 +167,18 @@ class FileViewFinder implements ViewFinderInterface
|
||||
*/
|
||||
public function prependLocation($location)
|
||||
{
|
||||
array_unshift($this->paths, $location);
|
||||
array_unshift($this->paths, $this->resolvePath($location));
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve the path.
|
||||
*
|
||||
* @param string $path
|
||||
* @return string
|
||||
*/
|
||||
protected function resolvePath($path)
|
||||
{
|
||||
return realpath($path) ?: $path;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -266,6 +275,19 @@ class FileViewFinder implements ViewFinderInterface
|
||||
return $this->files;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the active view paths.
|
||||
*
|
||||
* @param array $paths
|
||||
* @return $this
|
||||
*/
|
||||
public function setPaths($paths)
|
||||
{
|
||||
$this->paths = $paths;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the active view paths.
|
||||
*
|
||||
@@ -276,6 +298,16 @@ class FileViewFinder implements ViewFinderInterface
|
||||
return $this->paths;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the views that have been located.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getViews()
|
||||
{
|
||||
return $this->views;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the namespace to file path hints.
|
||||
*
|
||||
|
||||
96
vendor/laravel/framework/src/Illuminate/View/InvokableComponentVariable.php
vendored
Normal file
96
vendor/laravel/framework/src/Illuminate/View/InvokableComponentVariable.php
vendored
Normal file
@@ -0,0 +1,96 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\View;
|
||||
|
||||
use ArrayIterator;
|
||||
use Closure;
|
||||
use Illuminate\Contracts\Support\DeferringDisplayableValue;
|
||||
use Illuminate\Support\Enumerable;
|
||||
use IteratorAggregate;
|
||||
use Traversable;
|
||||
|
||||
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(): Traversable
|
||||
{
|
||||
$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();
|
||||
}
|
||||
}
|
||||
21
vendor/laravel/framework/src/Illuminate/View/LICENSE.md
vendored
Normal file
21
vendor/laravel/framework/src/Illuminate/View/LICENSE.md
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) Taylor Otwell
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
@@ -3,8 +3,8 @@
|
||||
namespace Illuminate\View\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Support\ViewErrorBag;
|
||||
use Illuminate\Contracts\View\Factory as ViewFactory;
|
||||
use Illuminate\Support\ViewErrorBag;
|
||||
|
||||
class ShareErrorsFromSession
|
||||
{
|
||||
|
||||
@@ -2,20 +2,26 @@
|
||||
|
||||
namespace Illuminate\View;
|
||||
|
||||
use Exception;
|
||||
use Throwable;
|
||||
use ArrayAccess;
|
||||
use BadMethodCallException;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Support\MessageBag;
|
||||
use Illuminate\Contracts\Support\Arrayable;
|
||||
use Illuminate\Contracts\Support\Renderable;
|
||||
use Illuminate\View\Engines\EngineInterface;
|
||||
use Illuminate\Contracts\Support\Htmlable;
|
||||
use Illuminate\Contracts\Support\MessageProvider;
|
||||
use Illuminate\Contracts\Support\Renderable;
|
||||
use Illuminate\Contracts\View\Engine;
|
||||
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, ViewContract
|
||||
class View implements ArrayAccess, Htmlable, ViewContract
|
||||
{
|
||||
use Macroable {
|
||||
__call as macroCall;
|
||||
}
|
||||
|
||||
/**
|
||||
* The view factory instance.
|
||||
*
|
||||
@@ -26,7 +32,7 @@ class View implements ArrayAccess, ViewContract
|
||||
/**
|
||||
* The engine implementation.
|
||||
*
|
||||
* @var \Illuminate\View\Engines\EngineInterface
|
||||
* @var \Illuminate\Contracts\View\Engine
|
||||
*/
|
||||
protected $engine;
|
||||
|
||||
@@ -55,13 +61,13 @@ class View implements ArrayAccess, ViewContract
|
||||
* Create a new view instance.
|
||||
*
|
||||
* @param \Illuminate\View\Factory $factory
|
||||
* @param \Illuminate\View\Engines\EngineInterface $engine
|
||||
* @param \Illuminate\Contracts\View\Engine $engine
|
||||
* @param string $view
|
||||
* @param string $path
|
||||
* @param mixed $data
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Factory $factory, EngineInterface $engine, $view, $path, $data = [])
|
||||
public function __construct(Factory $factory, Engine $engine, $view, $path, $data = [])
|
||||
{
|
||||
$this->view = $view;
|
||||
$this->path = $path;
|
||||
@@ -71,6 +77,19 @@ class View implements ArrayAccess, ViewContract
|
||||
$this->data = $data instanceof Arrayable ? $data->toArray() : (array) $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the evaluated contents of a given fragment.
|
||||
*
|
||||
* @param string $fragment
|
||||
* @return string
|
||||
*/
|
||||
public function fragment($fragment)
|
||||
{
|
||||
return $this->render(function () use ($fragment) {
|
||||
return $this->factory->getFragment($fragment);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the string contents of the view.
|
||||
*
|
||||
@@ -84,7 +103,7 @@ class View implements ArrayAccess, ViewContract
|
||||
try {
|
||||
$contents = $this->renderContents();
|
||||
|
||||
$response = isset($callback) ? call_user_func($callback, $this, $contents) : null;
|
||||
$response = isset($callback) ? $callback($this, $contents) : null;
|
||||
|
||||
// Once we have the contents of the view, we will flush the sections if we are
|
||||
// done rendering all views so that there is nothing left hanging over when
|
||||
@@ -92,10 +111,6 @@ class View implements ArrayAccess, ViewContract
|
||||
$this->factory->flushStateIfDoneRendering();
|
||||
|
||||
return ! is_null($response) ? $response : $contents;
|
||||
} catch (Exception $e) {
|
||||
$this->factory->flushState();
|
||||
|
||||
throw $e;
|
||||
} catch (Throwable $e) {
|
||||
$this->factory->flushState();
|
||||
|
||||
@@ -110,7 +125,7 @@ class View implements ArrayAccess, ViewContract
|
||||
*/
|
||||
protected function renderContents()
|
||||
{
|
||||
// We will keep track of the amount of views being rendered so we can flush
|
||||
// We will keep track of the number of views being rendered so we can flush
|
||||
// the section after the complete rendering operation is done. This will
|
||||
// clear out the sections for any separate views that may be rendered.
|
||||
$this->factory->incrementRender();
|
||||
@@ -120,7 +135,7 @@ class View implements ArrayAccess, ViewContract
|
||||
$contents = $this->getContents();
|
||||
|
||||
// Once we've finished rendering the view, we'll decrement the render count
|
||||
// so that each sections get flushed out next time a view is created and
|
||||
// so that each section gets flushed out next time a view is created and
|
||||
// no old sections are staying around in the memory of an environment.
|
||||
$this->factory->decrementRender();
|
||||
|
||||
@@ -142,7 +157,7 @@ class View implements ArrayAccess, ViewContract
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function gatherData()
|
||||
public function gatherData()
|
||||
{
|
||||
$data = array_merge($this->factory->getShared(), $this->data);
|
||||
|
||||
@@ -159,6 +174,8 @@ class View implements ArrayAccess, ViewContract
|
||||
* Get the sections of the rendered view.
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @throws \Throwable
|
||||
*/
|
||||
public function renderSections()
|
||||
{
|
||||
@@ -171,7 +188,7 @@ class View implements ArrayAccess, ViewContract
|
||||
* Add a piece of data to the view.
|
||||
*
|
||||
* @param string|array $key
|
||||
* @param mixed $value
|
||||
* @param mixed $value
|
||||
* @return $this
|
||||
*/
|
||||
public function with($key, $value = null)
|
||||
@@ -190,7 +207,7 @@ class View implements ArrayAccess, ViewContract
|
||||
*
|
||||
* @param string $key
|
||||
* @param string $view
|
||||
* @param array $data
|
||||
* @param array $data
|
||||
* @return $this
|
||||
*/
|
||||
public function nest($key, $view, array $data = [])
|
||||
@@ -202,25 +219,27 @@ class View implements ArrayAccess, 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);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -287,7 +306,7 @@ class View implements ArrayAccess, ViewContract
|
||||
/**
|
||||
* Get the view's rendering engine.
|
||||
*
|
||||
* @return \Illuminate\View\Engines\EngineInterface
|
||||
* @return \Illuminate\Contracts\View\Engine
|
||||
*/
|
||||
public function getEngine()
|
||||
{
|
||||
@@ -300,7 +319,7 @@ class View implements ArrayAccess, ViewContract
|
||||
* @param string $key
|
||||
* @return bool
|
||||
*/
|
||||
public function offsetExists($key)
|
||||
public function offsetExists($key): bool
|
||||
{
|
||||
return array_key_exists($key, $this->data);
|
||||
}
|
||||
@@ -311,7 +330,7 @@ class View implements ArrayAccess, ViewContract
|
||||
* @param string $key
|
||||
* @return mixed
|
||||
*/
|
||||
public function offsetGet($key)
|
||||
public function offsetGet($key): mixed
|
||||
{
|
||||
return $this->data[$key];
|
||||
}
|
||||
@@ -320,10 +339,10 @@ class View implements ArrayAccess, ViewContract
|
||||
* Set a piece of data on the view.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @param mixed $value
|
||||
* @return void
|
||||
*/
|
||||
public function offsetSet($key, $value)
|
||||
public function offsetSet($key, $value): void
|
||||
{
|
||||
$this->with($key, $value);
|
||||
}
|
||||
@@ -334,7 +353,7 @@ class View implements ArrayAccess, ViewContract
|
||||
* @param string $key
|
||||
* @return void
|
||||
*/
|
||||
public function offsetUnset($key)
|
||||
public function offsetUnset($key): void
|
||||
{
|
||||
unset($this->data[$key]);
|
||||
}
|
||||
@@ -354,7 +373,7 @@ class View implements ArrayAccess, ViewContract
|
||||
* Set a piece of data on the view.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @param mixed $value
|
||||
* @return void
|
||||
*/
|
||||
public function __set($key, $value)
|
||||
@@ -377,7 +396,7 @@ class View implements ArrayAccess, ViewContract
|
||||
* Remove a piece of bound data from the view.
|
||||
*
|
||||
* @param string $key
|
||||
* @return bool
|
||||
* @return void
|
||||
*/
|
||||
public function __unset($key)
|
||||
{
|
||||
@@ -388,24 +407,42 @@ class View implements ArrayAccess, ViewContract
|
||||
* Dynamically bind parameters to the view.
|
||||
*
|
||||
* @param string $method
|
||||
* @param array $parameters
|
||||
* @param array $parameters
|
||||
* @return \Illuminate\View\View
|
||||
*
|
||||
* @throws \BadMethodCallException
|
||||
*/
|
||||
public function __call($method, $parameters)
|
||||
{
|
||||
if (! Str::startsWith($method, 'with')) {
|
||||
throw new BadMethodCallException("Method [$method] does not exist on view.");
|
||||
if (static::hasMacro($method)) {
|
||||
return $this->macroCall($method, $parameters);
|
||||
}
|
||||
|
||||
return $this->with(Str::snake(substr($method, 4)), $parameters[0]);
|
||||
if (! str_starts_with($method, 'with')) {
|
||||
throw new BadMethodCallException(sprintf(
|
||||
'Method %s::%s does not exist.', static::class, $method
|
||||
));
|
||||
}
|
||||
|
||||
return $this->with(Str::camel(substr($method, 4)), $parameters[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get content as a string of HTML.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function toHtml()
|
||||
{
|
||||
return $this->render();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the string contents of the view.
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @throws \Throwable
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
|
||||
41
vendor/laravel/framework/src/Illuminate/View/ViewException.php
vendored
Normal file
41
vendor/laravel/framework/src/Illuminate/View/ViewException.php
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\View;
|
||||
|
||||
use ErrorException;
|
||||
use Illuminate\Container\Container;
|
||||
use Illuminate\Support\Reflector;
|
||||
|
||||
class ViewException extends ErrorException
|
||||
{
|
||||
/**
|
||||
* Report the exception.
|
||||
*
|
||||
* @return bool|null
|
||||
*/
|
||||
public function report()
|
||||
{
|
||||
$exception = $this->getPrevious();
|
||||
|
||||
if (Reflector::isCallable($reportCallable = [$exception, 'report'])) {
|
||||
return Container::getInstance()->call($reportCallable);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the exception into an HTTP response.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\Response|null
|
||||
*/
|
||||
public function render($request)
|
||||
{
|
||||
$exception = $this->getPrevious();
|
||||
|
||||
if ($exception && method_exists($exception, 'render')) {
|
||||
return $exception->render($request);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -50,7 +50,7 @@ interface ViewFinderInterface
|
||||
*
|
||||
* @param string $namespace
|
||||
* @param string|array $hints
|
||||
* @return $this
|
||||
* @return void
|
||||
*/
|
||||
public function replaceNamespace($namespace, $hints);
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ namespace Illuminate\View;
|
||||
class ViewName
|
||||
{
|
||||
/**
|
||||
* Normalize the given event name.
|
||||
* Normalize the given view name.
|
||||
*
|
||||
* @param string $name
|
||||
* @return string
|
||||
@@ -14,11 +14,11 @@ class ViewName
|
||||
{
|
||||
$delimiter = ViewFinderInterface::HINT_PATH_DELIMITER;
|
||||
|
||||
if (strpos($name, $delimiter) === false) {
|
||||
if (! str_contains($name, $delimiter)) {
|
||||
return str_replace('/', '.', $name);
|
||||
}
|
||||
|
||||
list($namespace, $name) = explode($delimiter, $name);
|
||||
[$namespace, $name] = explode($delimiter, $name);
|
||||
|
||||
return $namespace.$delimiter.str_replace('/', '.', $name);
|
||||
}
|
||||
|
||||
@@ -2,12 +2,12 @@
|
||||
|
||||
namespace Illuminate\View;
|
||||
|
||||
use Illuminate\View\Engines\PhpEngine;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use Illuminate\View\Engines\FileEngine;
|
||||
use Illuminate\View\Compilers\BladeCompiler;
|
||||
use Illuminate\View\Engines\CompilerEngine;
|
||||
use Illuminate\View\Engines\EngineResolver;
|
||||
use Illuminate\View\Compilers\BladeCompiler;
|
||||
use Illuminate\View\Engines\FileEngine;
|
||||
use Illuminate\View\Engines\PhpEngine;
|
||||
|
||||
class ViewServiceProvider extends ServiceProvider
|
||||
{
|
||||
@@ -19,10 +19,13 @@ class ViewServiceProvider extends ServiceProvider
|
||||
public function register()
|
||||
{
|
||||
$this->registerFactory();
|
||||
|
||||
$this->registerViewFinder();
|
||||
|
||||
$this->registerBladeCompiler();
|
||||
$this->registerEngineResolver();
|
||||
|
||||
$this->app->terminating(static function () {
|
||||
Component::flushCache();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -40,19 +43,36 @@ class ViewServiceProvider extends ServiceProvider
|
||||
|
||||
$finder = $app['view.finder'];
|
||||
|
||||
$env = new Factory($resolver, $finder, $app['events']);
|
||||
$factory = $this->createFactory($resolver, $finder, $app['events']);
|
||||
|
||||
// We will also set the container instance on this view environment since the
|
||||
// view composers may be classes registered in the container, which allows
|
||||
// for great testable, flexible composers for the application developer.
|
||||
$env->setContainer($app);
|
||||
$factory->setContainer($app);
|
||||
|
||||
$env->share('app', $app);
|
||||
$factory->share('app', $app);
|
||||
|
||||
return $env;
|
||||
$app->terminating(static function () {
|
||||
Component::forgetFactory();
|
||||
});
|
||||
|
||||
return $factory;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new Factory Instance.
|
||||
*
|
||||
* @param \Illuminate\View\Engines\EngineResolver $resolver
|
||||
* @param \Illuminate\View\ViewFinderInterface $finder
|
||||
* @param \Illuminate\Contracts\Events\Dispatcher $events
|
||||
* @return \Illuminate\View\Factory
|
||||
*/
|
||||
protected function createFactory($resolver, $finder, $events)
|
||||
{
|
||||
return new Factory($resolver, $finder, $events);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the view finder implementation.
|
||||
*
|
||||
@@ -65,6 +85,26 @@ class ViewServiceProvider extends ServiceProvider
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the Blade compiler implementation.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function registerBladeCompiler()
|
||||
{
|
||||
$this->app->singleton('blade.compiler', function ($app) {
|
||||
return tap(new BladeCompiler(
|
||||
$app['files'],
|
||||
$app['config']['view.compiled'],
|
||||
$app['config']->get('view.relative_hash', false) ? $app->basePath() : '',
|
||||
$app['config']->get('view.cache', true),
|
||||
$app['config']->get('view.compiled_extension', 'php'),
|
||||
), function ($blade) {
|
||||
$blade->component('dynamic-component', DynamicComponent::class);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the engine resolver instance.
|
||||
*
|
||||
@@ -95,7 +135,7 @@ class ViewServiceProvider extends ServiceProvider
|
||||
public function registerFileEngine($resolver)
|
||||
{
|
||||
$resolver->register('file', function () {
|
||||
return new FileEngine;
|
||||
return new FileEngine($this->app['files']);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -108,7 +148,7 @@ class ViewServiceProvider extends ServiceProvider
|
||||
public function registerPhpEngine($resolver)
|
||||
{
|
||||
$resolver->register('php', function () {
|
||||
return new PhpEngine;
|
||||
return new PhpEngine($this->app['files']);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -120,17 +160,14 @@ class ViewServiceProvider extends ServiceProvider
|
||||
*/
|
||||
public function registerBladeEngine($resolver)
|
||||
{
|
||||
// The Compiler engine requires an instance of the CompilerInterface, which in
|
||||
// this case will be the Blade compiler, so we'll first create the compiler
|
||||
// instance to pass into the engine so it can compile the views properly.
|
||||
$this->app->singleton('blade.compiler', function () {
|
||||
return new BladeCompiler(
|
||||
$this->app['files'], $this->app['config']['view.compiled']
|
||||
);
|
||||
});
|
||||
|
||||
$resolver->register('blade', function () {
|
||||
return new CompilerEngine($this->app['blade.compiler']);
|
||||
$compiler = new CompilerEngine($this->app['blade.compiler'], $this->app['files']);
|
||||
|
||||
$this->app->terminating(static function () use ($compiler) {
|
||||
$compiler->forgetCompiledOrNotExpired();
|
||||
});
|
||||
|
||||
return $compiler;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,13 +14,15 @@
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=5.6.4",
|
||||
"illuminate/container": "5.4.*",
|
||||
"illuminate/contracts": "5.4.*",
|
||||
"illuminate/events": "5.4.*",
|
||||
"illuminate/filesystem": "5.4.*",
|
||||
"illuminate/support": "5.4.*",
|
||||
"symfony/debug": "~3.2"
|
||||
"php": "^8.0.2",
|
||||
"ext-json": "*",
|
||||
"illuminate/collections": "^9.0",
|
||||
"illuminate/container": "^9.0",
|
||||
"illuminate/contracts": "^9.0",
|
||||
"illuminate/events": "^9.0",
|
||||
"illuminate/filesystem": "^9.0",
|
||||
"illuminate/macroable": "^9.0",
|
||||
"illuminate/support": "^9.0"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
@@ -29,7 +31,7 @@
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "5.4-dev"
|
||||
"dev-master": "9.x-dev"
|
||||
}
|
||||
},
|
||||
"config": {
|
||||
|
||||
Reference in New Issue
Block a user