package and depencies

This commit is contained in:
RafficMohammed
2023-01-08 02:57:24 +05:30
parent d5332eb421
commit 1d54b8bc7f
4309 changed files with 193331 additions and 172289 deletions

View File

@@ -21,6 +21,7 @@ class BladeCompiler extends Compiler implements CompilerInterface
Concerns\CompilesConditionals,
Concerns\CompilesEchos,
Concerns\CompilesErrors,
Concerns\CompilesFragments,
Concerns\CompilesHelpers,
Concerns\CompilesIncludes,
Concerns\CompilesInjections,
@@ -122,6 +123,20 @@ class BladeCompiler extends Compiler implements CompilerInterface
*/
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.
*
@@ -241,7 +256,7 @@ class BladeCompiler extends Compiler implements CompilerInterface
);
foreach ($this->precompilers as $precompiler) {
$value = call_user_func($precompiler, $value);
$value = $precompiler($value);
}
// Here we will loop through all of the tokens returned by the Zend lexer and
@@ -340,11 +355,11 @@ class BladeCompiler extends Compiler implements CompilerInterface
*/
protected function storeUncompiledBlocks($value)
{
if (strpos($value, '@verbatim') !== false) {
if (str_contains($value, '@verbatim')) {
$value = $this->storeVerbatimBlocks($value);
}
if (strpos($value, '@php') !== false) {
if (str_contains($value, '@php')) {
$value = $this->storePhpBlocks($value);
}
@@ -504,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];
@@ -524,9 +541,9 @@ class BladeCompiler extends Compiler implements CompilerInterface
*/
protected function callCustomDirective($name, $value)
{
$value = $value ?? '';
$value ??= '';
if (Str::startsWith($value, '(') && Str::endsWith($value, ')')) {
if (str_starts_with($value, '(') && str_ends_with($value, ')')) {
$value = Str::substr($value, 1, -1);
}
@@ -625,12 +642,12 @@ class BladeCompiler extends Compiler implements CompilerInterface
*/
public function component($class, $alias = null, $prefix = '')
{
if (! is_null($alias) && Str::contains($alias, '\\')) {
if (! is_null($alias) && str_contains($alias, '\\')) {
[$class, $alias] = [$alias, $class];
}
if (is_null($alias)) {
$alias = Str::contains($class, '\\View\\Components\\')
$alias = str_contains($class, '\\View\\Components\\')
? collect(explode('\\', Str::after($class, '\\View\\Components\\')))->map(function ($segment) {
return Str::kebab($segment);
})->implode(':')
@@ -672,6 +689,45 @@ class BladeCompiler extends Compiler implements CompilerInterface
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.
*
@@ -684,6 +740,26 @@ class BladeCompiler extends Compiler implements CompilerInterface
$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.
*

View File

@@ -3,34 +3,64 @@
namespace Illuminate\View\Compilers;
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('v2'.$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

View File

@@ -111,10 +111,18 @@ class ComponentTagCompiler
(?:
\s+
(?:
(?:
@(?:class)(\( (?: (?>[^()]+) | (?-1) )* \))
)
|
(?:
\{\{\s*\\\$attributes(?:[^}]+?)?\s*\}\}
)
|
(?:
(\:\\\$)(\w+)
)
|
(?:
[\w\-:.@]+
(
@@ -164,10 +172,18 @@ class ComponentTagCompiler
(?:
\s+
(?:
(?:
@(?:class)(\( (?: (?>[^()]+) | (?-1) )* \))
)
|
(?:
\{\{\s*\\\$attributes(?:[^}]+?)?\s*\}\}
)
|
(?:
(\:\\\$)(\w+)
)
|
(?:
[\w\-:.@]+
(
@@ -216,12 +232,16 @@ class ComponentTagCompiler
return [Str::camel($key) => $value];
});
// If the component doesn't exists as a class we'll assume it's a class-less
// 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' => "'$class'",
'view' => $view,
'data' => '['.$this->attributesToString($data->all(), $escapeBound = false).']',
];
@@ -231,6 +251,9 @@ class ComponentTagCompiler
}
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).']); ?>';
}
@@ -268,12 +291,13 @@ class ComponentTagCompiler
return $class;
}
if ($viewFactory->exists($view = $this->guessViewName($component))) {
return $view;
if (! is_null($guess = $this->guessAnonymousComponentUsingNamespaces($viewFactory, $component)) ||
! is_null($guess = $this->guessAnonymousComponentUsingPaths($viewFactory, $component))) {
return $guess;
}
if ($viewFactory->exists($view = $this->guessViewName($component).'.index')) {
return $view;
if (Str::startsWith($component, 'mail::')) {
return $component;
}
throw new InvalidArgumentException(
@@ -281,6 +305,72 @@ class ComponentTagCompiler
);
}
/**
* 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.
*
@@ -293,7 +383,7 @@ class ComponentTagCompiler
$prefix = $segments[0];
if (! isset($this->namespaces[$prefix]) || ! isset($segments[1])) {
if (! isset($this->namespaces[$prefix], $segments[1])) {
return;
}
@@ -338,15 +428,18 @@ class ComponentTagCompiler
* Guess the view name for the given component.
*
* @param string $name
* @param string $prefix
* @return string
*/
public function guessViewName($name)
public function guessViewName($name, $prefix = 'components.')
{
$prefix = 'components.';
if (! Str::endsWith($prefix, '.')) {
$prefix .= '.';
}
$delimiter = ViewFinderInterface::HINT_PATH_DELIMITER;
if (Str::contains($name, $delimiter)) {
if (str_contains($name, $delimiter)) {
return Str::replaceFirst($delimiter, $delimiter.$prefix, $name);
}
@@ -362,7 +455,7 @@ class ComponentTagCompiler
*/
public function partitionDataAndAttributes($class, array $attributes)
{
// If the class doesn't exists, we'll assume it's a class-less component and
// 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)) {
@@ -403,12 +496,16 @@ class ComponentTagCompiler
<
\s*
x[\-\:]slot
\s+
(:?)name=(?<name>(\"[^\"]+\"|\\\'[^\\\']+\\\'|[^\s>]+))
(?:\:(?<inlineName>\w+(?:-\w+)*))?
(?:\s+(:?)name=(?<name>(\"[^\"]+\"|\\\'[^\\\']+\\\'|[^\s>]+)))?
(?<attributes>
(?:
\s+
(?:
(?:
@(?:class)(\( (?: (?>[^()]+) | (?-1) )* \))
)
|
(?:
\{\{\s*\\\$attributes(?:[^}]+?)?\s*\}\}
)
@@ -435,9 +532,13 @@ class ComponentTagCompiler
/x";
$value = preg_replace_callback($pattern, function ($matches) {
$name = $this->stripQuotes($matches['name']);
$name = $this->stripQuotes($matches['inlineName'] ?: $matches['name']);
if ($matches[1] !== ':') {
if (Str::contains($name, '-') && ! empty($matches['inlineName'])) {
$name = Str::camel($name);
}
if ($matches[2] !== ':') {
$name = "'{$name}'";
}
@@ -459,8 +560,9 @@ class ComponentTagCompiler
*/
protected function getAttributesFromAttributeString(string $attributeString)
{
$attributeString = $this->parseShortAttributeSyntax($attributeString);
$attributeString = $this->parseAttributeBag($attributeString);
$attributeString = $this->parseComponentTagClassStatements($attributeString);
$attributeString = $this->parseBindAttributes($attributeString);
$pattern = '/
@@ -495,7 +597,7 @@ class ComponentTagCompiler
$value = $this->stripQuotes($value);
if (Str::startsWith($attribute, 'bind:')) {
if (str_starts_with($attribute, 'bind:')) {
$attribute = Str::after($attribute, 'bind:');
$this->boundAttributes[$attribute] = true;
@@ -503,7 +605,7 @@ class ComponentTagCompiler
$value = "'".$this->compileAttributeEchos($value)."'";
}
if (Str::startsWith($attribute, '::')) {
if (str_starts_with($attribute, '::')) {
$attribute = substr($attribute, 1);
}
@@ -511,6 +613,21 @@ class ComponentTagCompiler
})->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.
*
@@ -527,6 +644,27 @@ class ComponentTagCompiler
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.
*

View File

@@ -23,7 +23,7 @@ trait CompilesComponents
*/
protected function compileComponent($expression)
{
[$component, $alias, $data] = strpos($expression, ',') !== false
[$component, $alias, $data] = str_contains($expression, ',')
? array_map('trim', explode(',', trim($expression, '()'), 3)) + ['', '', '']
: [trim($expression, '()'), '', ''];
@@ -64,7 +64,7 @@ trait CompilesComponents
{
return implode("\n", [
'<?php if (isset($component)) { $__componentOriginal'.$hash.' = $component; } ?>',
'<?php $component = $__env->getContainer()->make('.Str::finish($component, '::class').', '.($data ?: '[]').'); ?>',
'<?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()); ?>',
@@ -149,7 +149,11 @@ trait CompilesComponents
*/
protected function compileProps($expression)
{
return "<?php \$attributes = \$attributes->exceptProps{$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;
} ?>
@@ -182,7 +186,7 @@ trait CompilesComponents
*/
public static function sanitizeComponentAttribute($value)
{
if (is_object($value) && $value instanceof CanBeEscapedWhenCastToString) {
if ($value instanceof CanBeEscapedWhenCastToString) {
return $value->escapeWhenCastingToString();
}

View File

@@ -304,4 +304,82 @@ trait CompilesConditionals
{
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; ?>';
}
}

View File

@@ -143,7 +143,7 @@ trait CompilesEchos
{
$value = Str::of($value)
->trim()
->when(Str::endsWith($value, ';'), function ($str) {
->when(str_ends_with($value, ';'), function ($str) {
return $str->beforeLast(';');
});

View 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(); ?>';
}
}

View File

@@ -2,6 +2,8 @@
namespace Illuminate\View\Compilers\Concerns;
use Illuminate\Foundation\Vite;
trait CompilesHelpers
{
/**
@@ -46,4 +48,31 @@ trait CompilesHelpers
{
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(); ?>";
}
}

View File

@@ -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]);

View File

@@ -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; ?>';
}
}