Pressroom template verwijderd, website naar root van repo

This commit is contained in:
2020-03-22 15:30:52 +01:00
parent 2cb6a77425
commit f3d1c41e91
7620 changed files with 0 additions and 186900 deletions

View File

@@ -0,0 +1,380 @@
<?php
namespace Illuminate\View\Compilers;
use Illuminate\Support\Arr;
use Illuminate\Support\Str;
class BladeCompiler extends Compiler implements CompilerInterface
{
use Concerns\CompilesAuthorizations,
Concerns\CompilesComments,
Concerns\CompilesComponents,
Concerns\CompilesConditionals,
Concerns\CompilesEchos,
Concerns\CompilesIncludes,
Concerns\CompilesInjections,
Concerns\CompilesLayouts,
Concerns\CompilesLoops,
Concerns\CompilesRawPhp,
Concerns\CompilesStacks,
Concerns\CompilesTranslations;
/**
* All of the registered extensions.
*
* @var array
*/
protected $extensions = [];
/**
* All custom "directive" handlers.
*
* This was implemented as a more usable "extend" in 5.1.
*
* @var array
*/
protected $customDirectives = [];
/**
* The file currently being compiled.
*
* @var string
*/
protected $path;
/**
* All of the available compiler functions.
*
* @var array
*/
protected $compilers = [
'Comments',
'Extensions',
'Statements',
'Echos',
];
/**
* Array of opening and closing tags for raw echos.
*
* @var array
*/
protected $rawTags = ['{!!', '!!}'];
/**
* Array of opening and closing tags for regular echos.
*
* @var array
*/
protected $contentTags = ['{{', '}}'];
/**
* Array of opening and closing tags for escaped echos.
*
* @var array
*/
protected $escapedTags = ['{{{', '}}}'];
/**
* The "regular" / legacy echo string format.
*
* @var string
*/
protected $echoFormat = 'e(%s)';
/**
* Array of footer lines to be added to 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.
*
* @var array
*/
protected $verbatimBlocks = [];
/**
* Compile the view at the given path.
*
* @param string $path
* @return void
*/
public function compile($path = null)
{
if ($path) {
$this->setPath($path);
}
if (! is_null($this->cachePath)) {
$contents = $this->compileString($this->files->get($this->getPath()));
$this->files->put($this->getCompiledPath($this->getPath()), $contents);
}
}
/**
* Get the path currently being compiled.
*
* @return string
*/
public function getPath()
{
return $this->path;
}
/**
* Set the path currently being compiled.
*
* @param string $path
* @return void
*/
public function setPath($path)
{
$this->path = $path;
}
/**
* Compile the given Blade template contents.
*
* @param string $value
* @return string
*/
public function compileString($value)
{
$result = '';
if (strpos($value, '@verbatim') !== false) {
$value = $this->storeVerbatimBlocks($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.
foreach (token_get_all($value) as $token) {
$result .= is_array($token) ? $this->parseToken($token) : $token;
}
if (! empty($this->verbatimBlocks)) {
$result = $this->restoreVerbatimBlocks($result);
}
// If there are any footer lines that need to get added to a template we will
// add them here at the end of the template. This gets used mainly for the
// template inheritance via the extends keyword that should be appended.
if (count($this->footer) > 0) {
$result = $this->addFooters($result);
}
return $result;
}
/**
* Store the verbatim blocks and replace them with a temporary placeholder.
*
* @param string $value
* @return string
*/
protected function storeVerbatimBlocks($value)
{
return preg_replace_callback('/(?<!@)@verbatim(.*?)@endverbatim/s', function ($matches) {
$this->verbatimBlocks[] = $matches[1];
return $this->verbatimPlaceholder;
}, $value);
}
/**
* Replace the raw placeholders with the original code stored in the raw blocks.
*
* @param string $result
* @return string
*/
protected function restoreVerbatimBlocks($result)
{
$result = preg_replace_callback('/'.preg_quote($this->verbatimPlaceholder).'/', function () {
return array_shift($this->verbatimBlocks);
}, $result);
$this->verbatimBlocks = [];
return $result;
}
/**
* Add the stored footers onto the given content.
*
* @param string $result
* @return string
*/
protected function addFooters($result)
{
return ltrim($result, PHP_EOL)
.PHP_EOL.implode(PHP_EOL, array_reverse($this->footer));
}
/**
* Parse the tokens from the template.
*
* @param array $token
* @return string
*/
protected function parseToken($token)
{
list($id, $content) = $token;
if ($id == T_INLINE_HTML) {
foreach ($this->compilers as $type) {
$content = $this->{"compile{$type}"}($content);
}
}
return $content;
}
/**
* Execute the user defined extensions.
*
* @param string $value
* @return string
*/
protected function compileExtensions($value)
{
foreach ($this->extensions as $compiler) {
$value = call_user_func($compiler, $value, $this);
}
return $value;
}
/**
* Compile Blade statements that start with "@".
*
* @param string $value
* @return string
*/
protected function compileStatements($value)
{
return preg_replace_callback(
'/\B@(@?\w+(?:::\w+)?)([ \t]*)(\( ( (?>[^()]+) | (?3) )* \))?/x', function ($match) {
return $this->compileStatement($match);
}, $value
);
}
/**
* Compile a single Blade @ statement.
*
* @param array $match
* @return string
*/
protected function compileStatement($match)
{
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));
}
return isset($match[3]) ? $match[0] : $match[0].$match[2];
}
/**
* Call the given directive with the given value.
*
* @param string $name
* @param string|null $value
* @return string
*/
protected function callCustomDirective($name, $value)
{
if (Str::startsWith($value, '(') && Str::endsWith($value, ')')) {
$value = Str::substr($value, 1, -1);
}
return call_user_func($this->customDirectives[$name], trim($value));
}
/**
* Strip the parentheses from the given expression.
*
* @param string $expression
* @return string
*/
public function stripParentheses($expression)
{
if (Str::startsWith($expression, '(')) {
$expression = substr($expression, 1, -1);
}
return $expression;
}
/**
* Register a custom Blade compiler.
*
* @param callable $compiler
* @return void
*/
public function extend(callable $compiler)
{
$this->extensions[] = $compiler;
}
/**
* Get the extensions used by the compiler.
*
* @return array
*/
public function getExtensions()
{
return $this->extensions;
}
/**
* Register a handler for custom directives.
*
* @param string $name
* @param callable $handler
* @return void
*/
public function directive($name, callable $handler)
{
$this->customDirectives[$name] = $handler;
}
/**
* Get the list of custom directives.
*
* @return array
*/
public function getCustomDirectives()
{
return $this->customDirectives;
}
/**
* Set the echo format to be used by the compiler.
*
* @param string $format
* @return void
*/
public function setEchoFormat($format)
{
$this->echoFormat = $format;
}
}

View File

@@ -0,0 +1,74 @@
<?php
namespace Illuminate\View\Compilers;
use InvalidArgumentException;
use Illuminate\Filesystem\Filesystem;
abstract class Compiler
{
/**
* The Filesystem instance.
*
* @var \Illuminate\Filesystem\Filesystem
*/
protected $files;
/**
* Get the cache path for the compiled views.
*
* @var string
*/
protected $cachePath;
/**
* Create a new compiler instance.
*
* @param \Illuminate\Filesystem\Filesystem $files
* @param string $cachePath
* @return void
*
* @throws \InvalidArgumentException
*/
public function __construct(Filesystem $files, $cachePath)
{
if (! $cachePath) {
throw new InvalidArgumentException('Please provide a valid cache path.');
}
$this->files = $files;
$this->cachePath = $cachePath;
}
/**
* Get the path to the compiled version of a view.
*
* @param string $path
* @return string
*/
public function getCompiledPath($path)
{
return $this->cachePath.'/'.sha1($path).'.php';
}
/**
* Determine if the view at the given path is expired.
*
* @param string $path
* @return bool
*/
public function isExpired($path)
{
$compiled = $this->getCompiledPath($path);
// If the compiled file doesn't exist we will indicate that the view is expired
// so that it can be re-compiled. Else, we will verify the last modification
// of the views is less than the modification times of the compiled views.
if (! $this->files->exists($compiled)) {
return true;
}
return $this->files->lastModified($path) >=
$this->files->lastModified($compiled);
}
}

View File

@@ -0,0 +1,30 @@
<?php
namespace Illuminate\View\Compilers;
interface CompilerInterface
{
/**
* Get the path to the compiled version of a view.
*
* @param string $path
* @return string
*/
public function getCompiledPath($path);
/**
* Determine if the given view is expired.
*
* @param string $path
* @return bool
*/
public function isExpired($path);
/**
* Compile the view at the given path.
*
* @param string $path
* @return void
*/
public function compile($path);
}

View File

@@ -0,0 +1,70 @@
<?php
namespace Illuminate\View\Compilers\Concerns;
trait CompilesAuthorizations
{
/**
* Compile the can statements into valid PHP.
*
* @param string $expression
* @return string
*/
protected function compileCan($expression)
{
return "<?php if (app(\Illuminate\\Contracts\\Auth\\Access\\Gate::class)->check{$expression}): ?>";
}
/**
* Compile the cannot statements into valid PHP.
*
* @param string $expression
* @return string
*/
protected function compileCannot($expression)
{
return "<?php if (app(\Illuminate\\Contracts\\Auth\\Access\\Gate::class)->denies{$expression}): ?>";
}
/**
* Compile the else-can statements into valid PHP.
*
* @param string $expression
* @return string
*/
protected function compileElsecan($expression)
{
return "<?php elseif (app(\Illuminate\\Contracts\\Auth\\Access\\Gate::class)->check{$expression}): ?>";
}
/**
* Compile the else-cannot statements into valid PHP.
*
* @param string $expression
* @return string
*/
protected function compileElsecannot($expression)
{
return "<?php elseif (app(\Illuminate\\Contracts\\Auth\\Access\\Gate::class)->denies{$expression}): ?>";
}
/**
* Compile the end-can statements into valid PHP.
*
* @return string
*/
protected function compileEndcan()
{
return '<?php endif; ?>';
}
/**
* Compile the end-cannot statements into valid PHP.
*
* @return string
*/
protected function compileEndcannot()
{
return '<?php endif; ?>';
}
}

View File

@@ -0,0 +1,19 @@
<?php
namespace Illuminate\View\Compilers\Concerns;
trait CompilesComments
{
/**
* Compile Blade comments into an empty string.
*
* @param string $value
* @return string
*/
protected function compileComments($value)
{
$pattern = sprintf('/%s--(.*?)--%s/s', $this->contentTags[0], $this->contentTags[1]);
return preg_replace($pattern, '', $value);
}
}

View File

@@ -0,0 +1,48 @@
<?php
namespace Illuminate\View\Compilers\Concerns;
trait CompilesComponents
{
/**
* Compile the component statements into valid PHP.
*
* @param string $expression
* @return string
*/
protected function compileComponent($expression)
{
return "<?php \$__env->startComponent{$expression}; ?>";
}
/**
* Compile the end-component statements into valid PHP.
*
* @return string
*/
protected function compileEndComponent()
{
return '<?php echo $__env->renderComponent(); ?>';
}
/**
* Compile the slot statements into valid PHP.
*
* @param string $expression
* @return string
*/
protected function compileSlot($expression)
{
return "<?php \$__env->slot{$expression}; ?>";
}
/**
* Compile the end-slot statements into valid PHP.
*
* @return string
*/
protected function compileEndSlot()
{
return '<?php $__env->endSlot(); ?>';
}
}

View File

@@ -0,0 +1,147 @@
<?php
namespace Illuminate\View\Compilers\Concerns;
trait CompilesConditionals
{
/**
* 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 if-auth statements into valid PHP.
*
* @param string|null $guard
* @return string
*/
protected function compileAuth($guard = null)
{
$guard = is_null($guard) ? '()' : $guard;
return "<?php if(auth()->guard{$guard}->check()): ?>";
}
/**
* Compile the end-auth statements into valid PHP.
*
* @return string
*/
protected function compileEndAuth()
{
return '<?php endif; ?>';
}
/**
* Compile the if-guest statements into valid PHP.
*
* @param string|null $guard
* @return string
*/
protected function compileGuest($guard = null)
{
$guard = is_null($guard) ? '()' : $guard;
return "<?php if(auth()->guard{$guard}->guest()): ?>";
}
/**
* Compile the end-guest statements into valid PHP.
*
* @return string
*/
protected function compileEndGuest()
{
return '<?php endif; ?>';
}
/**
* Compile the if statements into valid PHP.
*
* @param string $expression
* @return string
*/
protected function compileIf($expression)
{
return "<?php if{$expression}: ?>";
}
/**
* Compile the unless statements into valid PHP.
*
* @param string $expression
* @return string
*/
protected function compileUnless($expression)
{
return "<?php if (! {$expression}): ?>";
}
/**
* Compile the else-if statements into valid PHP.
*
* @param string $expression
* @return string
*/
protected function compileElseif($expression)
{
return "<?php elseif{$expression}: ?>";
}
/**
* Compile the else statements into valid PHP.
*
* @return string
*/
protected function compileElse()
{
return '<?php else: ?>';
}
/**
* Compile the end-if statements into valid PHP.
*
* @return string
*/
protected function compileEndif()
{
return '<?php endif; ?>';
}
/**
* Compile the end-unless statements into valid PHP.
*
* @return string
*/
protected function compileEndunless()
{
return '<?php endif; ?>';
}
/**
* Compile the if-isset statements into valid PHP.
*
* @param string $expression
* @return string
*/
protected function compileIsset($expression)
{
return "<?php if(isset{$expression}): ?>";
}
/**
* Compile the end-isset statements into valid PHP.
*
* @return string
*/
protected function compileEndIsset()
{
return '<?php endif; ?>';
}
}

View File

@@ -0,0 +1,105 @@
<?php
namespace Illuminate\View\Compilers\Concerns;
trait CompilesEchos
{
/**
* Compile Blade echos into valid PHP.
*
* @param string $value
* @return string
*/
protected function compileEchos($value)
{
foreach ($this->getEchoMethods() as $method) {
$value = $this->$method($value);
}
return $value;
}
/**
* Get the echo methods in the proper order for compilation.
*
* @return array
*/
protected function getEchoMethods()
{
return [
'compileRawEchos',
'compileEscapedEchos',
'compileRegularEchos',
];
}
/**
* Compile the "raw" echo statements.
*
* @param string $value
* @return string
*/
protected function compileRawEchos($value)
{
$pattern = sprintf('/(@)?%s\s*(.+?)\s*%s(\r?\n)?/s', $this->rawTags[0], $this->rawTags[1]);
$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 preg_replace_callback($pattern, $callback, $value);
}
/**
* Compile the "regular" echo statements.
*
* @param string $value
* @return string
*/
protected function compileRegularEchos($value)
{
$pattern = sprintf('/(@)?%s\s*(.+?)\s*%s(\r?\n)?/s', $this->contentTags[0], $this->contentTags[1]);
$callback = function ($matches) {
$whitespace = empty($matches[3]) ? '' : $matches[3].$matches[3];
$wrapped = sprintf($this->echoFormat, $this->compileEchoDefaults($matches[2]));
return $matches[1] ? substr($matches[0], 1) : "<?php echo {$wrapped}; ?>{$whitespace}";
};
return preg_replace_callback($pattern, $callback, $value);
}
/**
* Compile the escaped echo statements.
*
* @param string $value
* @return string
*/
protected function compileEscapedEchos($value)
{
$pattern = sprintf('/(@)?%s\s*(.+?)\s*%s(\r?\n)?/s', $this->escapedTags[0], $this->escapedTags[1]);
$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 preg_replace_callback($pattern, $callback, $value);
}
/**
* Compile the default values for the echo statement.
*
* @param string $value
* @return string
*/
public function compileEchoDefaults($value)
{
return preg_replace('/^(?=\$)(.+?)(?:\s+or\s+)(.+?)$/s', 'isset($1) ? $1 : $2', $value);
}
}

View File

@@ -0,0 +1,56 @@
<?php
namespace Illuminate\View\Compilers\Concerns;
trait CompilesIncludes
{
/**
* Compile the each statements into valid PHP.
*
* @param string $expression
* @return string
*/
protected function compileEach($expression)
{
return "<?php echo \$__env->renderEach{$expression}; ?>";
}
/**
* Compile the include statements into valid PHP.
*
* @param string $expression
* @return string
*/
protected function compileInclude($expression)
{
$expression = $this->stripParentheses($expression);
return "<?php echo \$__env->make({$expression}, array_except(get_defined_vars(), array('__data', '__path')))->render(); ?>";
}
/**
* Compile the include-if statements into valid PHP.
*
* @param string $expression
* @return string
*/
protected function compileIncludeIf($expression)
{
$expression = $this->stripParentheses($expression);
return "<?php if (\$__env->exists({$expression})) echo \$__env->make({$expression}, array_except(get_defined_vars(), array('__data', '__path')))->render(); ?>";
}
/**
* Compile the include-when statements into valid PHP.
*
* @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'))); ?>";
}
}

View File

@@ -0,0 +1,23 @@
<?php
namespace Illuminate\View\Compilers\Concerns;
trait CompilesInjections
{
/**
* Compile the inject statements into valid PHP.
*
* @param string $expression
* @return string
*/
protected function compileInject($expression)
{
$segments = explode(',', preg_replace("/[\(\)\\\"\']/", '', $expression));
$variable = trim($segments[0]);
$service = trim($segments[1]);
return "<?php \${$variable} = app('{$service}'); ?>";
}
}

View File

@@ -0,0 +1,116 @@
<?php
namespace Illuminate\View\Compilers\Concerns;
use Illuminate\View\Factory as ViewFactory;
trait CompilesLayouts
{
/**
* The name of the last section that was started.
*
* @var string
*/
protected $lastSection;
/**
* Compile the extends statements into valid PHP.
*
* @param string $expression
* @return string
*/
protected function compileExtends($expression)
{
$expression = $this->stripParentheses($expression);
$echo = "<?php echo \$__env->make({$expression}, array_except(get_defined_vars(), array('__data', '__path')))->render(); ?>";
$this->footer[] = $echo;
return '';
}
/**
* Compile the section statements into valid PHP.
*
* @param string $expression
* @return string
*/
protected function compileSection($expression)
{
$this->lastSection = trim($expression, "()'\" ");
return "<?php \$__env->startSection{$expression}; ?>";
}
/**
* Replace the @parent directive to a placeholder.
*
* @return string
*/
protected function compileParent()
{
return ViewFactory::parentPlaceholder($this->lastSection ?: '');
}
/**
* Compile the yield statements into valid PHP.
*
* @param string $expression
* @return string
*/
protected function compileYield($expression)
{
return "<?php echo \$__env->yieldContent{$expression}; ?>";
}
/**
* Compile the show statements into valid PHP.
*
* @return string
*/
protected function compileShow()
{
return '<?php echo $__env->yieldSection(); ?>';
}
/**
* Compile the append statements into valid PHP.
*
* @return string
*/
protected function compileAppend()
{
return '<?php $__env->appendSection(); ?>';
}
/**
* Compile the overwrite statements into valid PHP.
*
* @return string
*/
protected function compileOverwrite()
{
return '<?php $__env->stopSection(true); ?>';
}
/**
* Compile the stop statements into valid PHP.
*
* @return string
*/
protected function compileStop()
{
return '<?php $__env->stopSection(); ?>';
}
/**
* Compile the end-section statements into valid PHP.
*
* @return string
*/
protected function compileEndsection()
{
return '<?php $__env->stopSection(); ?>';
}
}

View File

@@ -0,0 +1,180 @@
<?php
namespace Illuminate\View\Compilers\Concerns;
trait CompilesLoops
{
/**
* Counter to keep track of nested forelse statements.
*
* @var int
*/
protected $forElseCounter = 0;
/**
* Compile the for-else statements into valid PHP.
*
* @param string $expression
* @return string
*/
protected function compileForelse($expression)
{
$empty = '$__empty_'.++$this->forElseCounter;
preg_match('/\( *(.*) +as *(.*)\)$/is', $expression, $matches);
$iteratee = trim($matches[1]);
$iteration = trim($matches[2]);
$initLoop = "\$__currentLoopData = {$iteratee}; \$__env->addLoop(\$__currentLoopData);";
$iterateLoop = '$__env->incrementLoopIndices(); $loop = $__env->getLastLoop();';
return "<?php {$empty} = true; {$initLoop} foreach(\$__currentLoopData as {$iteration}): {$iterateLoop} {$empty} = false; ?>";
}
/**
* Compile the for-else-empty and empty statements into valid PHP.
*
* @param string $expression
* @return string
*/
protected function compileEmpty($expression)
{
if ($expression) {
return "<?php if(empty{$expression}): ?>";
}
$empty = '$__empty_'.$this->forElseCounter--;
return "<?php endforeach; \$__env->popLoop(); \$loop = \$__env->getLastLoop(); if ({$empty}): ?>";
}
/**
* Compile the end-for-else statements into valid PHP.
*
* @return string
*/
protected function compileEndforelse()
{
return '<?php endif; ?>';
}
/**
* Compile the end-empty statements into valid PHP.
*
* @return string
*/
protected function compileEndEmpty()
{
return '<?php endif; ?>';
}
/**
* Compile the for statements into valid PHP.
*
* @param string $expression
* @return string
*/
protected function compileFor($expression)
{
return "<?php for{$expression}: ?>";
}
/**
* Compile the for-each statements into valid PHP.
*
* @param string $expression
* @return string
*/
protected function compileForeach($expression)
{
preg_match('/\( *(.*) +as *(.*)\)$/is', $expression, $matches);
$iteratee = trim($matches[1]);
$iteration = trim($matches[2]);
$initLoop = "\$__currentLoopData = {$iteratee}; \$__env->addLoop(\$__currentLoopData);";
$iterateLoop = '$__env->incrementLoopIndices(); $loop = $__env->getLastLoop();';
return "<?php {$initLoop} foreach(\$__currentLoopData as {$iteration}): {$iterateLoop} ?>";
}
/**
* Compile the break statements into valid PHP.
*
* @param string $expression
* @return string
*/
protected function compileBreak($expression)
{
if ($expression) {
preg_match('/\(\s*(-?\d+)\s*\)$/', $expression, $matches);
return $matches ? '<?php break '.max(1, $matches[1]).'; ?>' : "<?php if{$expression} break; ?>";
}
return '<?php break; ?>';
}
/**
* Compile the continue statements into valid PHP.
*
* @param string $expression
* @return string
*/
protected function compileContinue($expression)
{
if ($expression) {
preg_match('/\(\s*(-?\d+)\s*\)$/', $expression, $matches);
return $matches ? '<?php continue '.max(1, $matches[1]).'; ?>' : "<?php if{$expression} continue; ?>";
}
return '<?php continue; ?>';
}
/**
* Compile the end-for statements into valid PHP.
*
* @return string
*/
protected function compileEndfor()
{
return '<?php endfor; ?>';
}
/**
* Compile the end-for-each statements into valid PHP.
*
* @return string
*/
protected function compileEndforeach()
{
return '<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>';
}
/**
* Compile the while statements into valid PHP.
*
* @param string $expression
* @return string
*/
protected function compileWhile($expression)
{
return "<?php while{$expression}: ?>";
}
/**
* Compile the end-while statements into valid PHP.
*
* @return string
*/
protected function compileEndwhile()
{
return '<?php endwhile; ?>';
}
}

View File

@@ -0,0 +1,38 @@
<?php
namespace Illuminate\View\Compilers\Concerns;
trait CompilesRawPhp
{
/**
* Compile the raw PHP statements into valid PHP.
*
* @param string $expression
* @return string
*/
protected function compilePhp($expression)
{
return $expression ? "<?php {$expression}; ?>" : '<?php ';
}
/**
* Compile end-php statements into valid PHP.
*
* @return string
*/
protected function compileEndphp()
{
return ' ?>';
}
/**
* Compile the unset statements into valid PHP.
*
* @param string $expression
* @return string
*/
protected function compileUnset($expression)
{
return "<?php unset{$expression}; ?>";
}
}

View File

@@ -0,0 +1,59 @@
<?php
namespace Illuminate\View\Compilers\Concerns;
trait CompilesStacks
{
/**
* Compile the stack statements into the content.
*
* @param string $expression
* @return string
*/
protected function compileStack($expression)
{
return "<?php echo \$__env->yieldPushContent{$expression}; ?>";
}
/**
* Compile the push statements into valid PHP.
*
* @param string $expression
* @return string
*/
protected function compilePush($expression)
{
return "<?php \$__env->startPush{$expression}; ?>";
}
/**
* Compile the end-push statements into valid PHP.
*
* @return string
*/
protected function compileEndpush()
{
return '<?php $__env->stopPush(); ?>';
}
/**
* Compile the prepend statements into valid PHP.
*
* @param string $expression
* @return string
*/
protected function compilePrepend($expression)
{
return "<?php \$__env->startPrepend{$expression}; ?>";
}
/**
* Compile the end-prepend statements into valid PHP.
*
* @return string
*/
protected function compileEndprepend()
{
return '<?php $__env->stopPrepend(); ?>';
}
}

View File

@@ -0,0 +1,44 @@
<?php
namespace Illuminate\View\Compilers\Concerns;
trait CompilesTranslations
{
/**
* Compile the lang statements into valid PHP.
*
* @param string $expression
* @return string
*/
protected function compileLang($expression)
{
if (is_null($expression)) {
return '<?php $__env->startTranslation(); ?>';
} elseif ($expression[1] === '[') {
return "<?php \$__env->startTranslation{$expression}; ?>";
} else {
return "<?php echo app('translator')->getFromJson{$expression}; ?>";
}
}
/**
* Compile the end-lang statements into valid PHP.
*
* @return string
*/
protected function compileEndlang()
{
return '<?php echo $__env->renderTranslation(); ?>';
}
/**
* Compile the choice statements into valid PHP.
*
* @param string $expression
* @return string
*/
protected function compileChoice($expression)
{
return "<?php echo app('translator')->choice{$expression}; ?>";
}
}

View File

@@ -0,0 +1,128 @@
<?php
namespace Illuminate\View\Concerns;
use Illuminate\Support\HtmlString;
trait ManagesComponents
{
/**
* The components being rendered.
*
* @var array
*/
protected $componentStack = [];
/**
* The original data passed to the component.
*
* @var array
*/
protected $componentData = [];
/**
* The slot contents for the component.
*
* @var array
*/
protected $slots = [];
/**
* The names of the slots being rendered.
*
* @var array
*/
protected $slotStack = [];
/**
* Start a component rendering process.
*
* @param string $name
* @param array $data
* @return void
*/
public function startComponent($name, array $data = [])
{
if (ob_start()) {
$this->componentStack[] = $name;
$this->componentData[$this->currentComponent()] = $data;
$this->slots[$this->currentComponent()] = [];
}
}
/**
* Render the current component.
*
* @return string
*/
public function renderComponent()
{
$name = array_pop($this->componentStack);
return $this->make($name, $this->componentData($name))->render();
}
/**
* Get the data for the given component.
*
* @param string $name
* @return array
*/
protected function componentData($name)
{
return array_merge(
$this->componentData[count($this->componentStack)],
['slot' => new HtmlString(trim(ob_get_clean()))],
$this->slots[count($this->componentStack)]
);
}
/**
* Start the slot rendering process.
*
* @param string $name
* @param string|null $content
* @return void
*/
public function slot($name, $content = null)
{
if (count(func_get_args()) == 2) {
$this->slots[$this->currentComponent()][$name] = $content;
} else {
if (ob_start()) {
$this->slots[$this->currentComponent()][$name] = '';
$this->slotStack[$this->currentComponent()][] = $name;
}
}
}
/**
* Save the slot content for rendering.
*
* @return void
*/
public function endSlot()
{
last($this->componentStack);
$currentSlot = array_pop(
$this->slotStack[$this->currentComponent()]
);
$this->slots[$this->currentComponent()]
[$currentSlot] = new HtmlString(trim(ob_get_clean()));
}
/**
* Get the index for the current component.
*
* @return int
*/
protected function currentComponent()
{
return count($this->componentStack) - 1;
}
}

View File

@@ -0,0 +1,192 @@
<?php
namespace Illuminate\View\Concerns;
use Closure;
use Illuminate\Support\Str;
use Illuminate\Contracts\View\View as ViewContract;
trait ManagesEvents
{
/**
* Register a view creator event.
*
* @param array|string $views
* @param \Closure|string $callback
* @return array
*/
public function creator($views, $callback)
{
$creators = [];
foreach ((array) $views as $view) {
$creators[] = $this->addViewEvent($view, $callback, 'creating: ');
}
return $creators;
}
/**
* Register multiple view composers via an array.
*
* @param array $composers
* @return array
*/
public function composers(array $composers)
{
$registered = [];
foreach ($composers as $callback => $views) {
$registered = array_merge($registered, $this->composer($views, $callback));
}
return $registered;
}
/**
* Register a view composer event.
*
* @param array|string $views
* @param \Closure|string $callback
* @return array
*/
public function composer($views, $callback)
{
$composers = [];
foreach ((array) $views as $view) {
$composers[] = $this->addViewEvent($view, $callback, 'composing: ');
}
return $composers;
}
/**
* Add an event for a given view.
*
* @param string $view
* @param \Closure|string $callback
* @param string $prefix
* @return \Closure|null
*/
protected function addViewEvent($view, $callback, $prefix = 'composing: ')
{
$view = $this->normalizeName($view);
if ($callback instanceof Closure) {
$this->addEventListener($prefix.$view, $callback);
return $callback;
} elseif (is_string($callback)) {
return $this->addClassEvent($view, $callback, $prefix);
}
}
/**
* Register a class based view composer.
*
* @param string $view
* @param string $class
* @param string $prefix
* @return \Closure
*/
protected function addClassEvent($view, $class, $prefix)
{
$name = $prefix.$view;
// When registering a class based view "composer", we will simply resolve the
// classes from the application IoC container then call the compose method
// on the instance. This allows for convenient, testable view composers.
$callback = $this->buildClassEventCallback(
$class, $prefix
);
$this->addEventListener($name, $callback);
return $callback;
}
/**
* Build a class based container callback Closure.
*
* @param string $class
* @param string $prefix
* @return \Closure
*/
protected function buildClassEventCallback($class, $prefix)
{
list($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()
);
};
}
/**
* Parse a class based composer name.
*
* @param string $class
* @param string $prefix
* @return array
*/
protected function parseClassEvent($class, $prefix)
{
return Str::parseCallback($class, $this->classEventMethodForPrefix($prefix));
}
/**
* Determine the class event method based on the given prefix.
*
* @param string $prefix
* @return string
*/
protected function classEventMethodForPrefix($prefix)
{
return Str::contains($prefix, 'composing') ? 'compose' : 'create';
}
/**
* Add a listener to the event dispatcher.
*
* @param string $name
* @param \Closure $callback
* @return void
*/
protected function addEventListener($name, $callback)
{
if (Str::contains($name, '*')) {
$callback = function ($name, array $data) use ($callback) {
return $callback($data[0]);
};
}
$this->events->listen($name, $callback);
}
/**
* Call the composer for a given view.
*
* @param \Illuminate\Contracts\View\View $view
* @return void
*/
public function callComposer(ViewContract $view)
{
$this->events->fire('composing: '.$view->name(), [$view]);
}
/**
* Call the creator for a given view.
*
* @param \Illuminate\Contracts\View\View $view
* @return void
*/
public function callCreator(ViewContract $view)
{
$this->events->fire('creating: '.$view->name(), [$view]);
}
}

View File

@@ -0,0 +1,218 @@
<?php
namespace Illuminate\View\Concerns;
use InvalidArgumentException;
use Illuminate\Contracts\View\View;
trait ManagesLayouts
{
/**
* All of the finished, captured sections.
*
* @var array
*/
protected $sections = [];
/**
* The stack of in-progress sections.
*
* @var array
*/
protected $sectionStack = [];
/**
* The parent placeholder for the request.
*
* @var string
*/
protected static $parentPlaceholder = [];
/**
* Start injecting content into a section.
*
* @param string $section
* @param string|null $content
* @return void
*/
public function startSection($section, $content = null)
{
if ($content === null) {
if (ob_start()) {
$this->sectionStack[] = $section;
}
} else {
$this->extendSection($section, $content instanceof View ? $content : e($content));
}
}
/**
* Inject inline content into a section.
*
* @param string $section
* @param string $content
* @return void
*/
public function inject($section, $content)
{
return $this->startSection($section, $content);
}
/**
* Stop injecting content into a section and return its contents.
*
* @return string
*/
public function yieldSection()
{
if (empty($this->sectionStack)) {
return '';
}
return $this->yieldContent($this->stopSection());
}
/**
* Stop injecting content into a section.
*
* @param bool $overwrite
* @return string
* @throws \InvalidArgumentException
*/
public function stopSection($overwrite = false)
{
if (empty($this->sectionStack)) {
throw new InvalidArgumentException('Cannot end a section without first starting one.');
}
$last = array_pop($this->sectionStack);
if ($overwrite) {
$this->sections[$last] = ob_get_clean();
} else {
$this->extendSection($last, ob_get_clean());
}
return $last;
}
/**
* Stop injecting content into a section and append it.
*
* @return string
* @throws \InvalidArgumentException
*/
public function appendSection()
{
if (empty($this->sectionStack)) {
throw new InvalidArgumentException('Cannot end a section without first starting one.');
}
$last = array_pop($this->sectionStack);
if (isset($this->sections[$last])) {
$this->sections[$last] .= ob_get_clean();
} else {
$this->sections[$last] = ob_get_clean();
}
return $last;
}
/**
* Append content to a given section.
*
* @param string $section
* @param string $content
* @return void
*/
protected function extendSection($section, $content)
{
if (isset($this->sections[$section])) {
$content = str_replace(static::parentPlaceholder($section), $content, $this->sections[$section]);
}
$this->sections[$section] = $content;
}
/**
* Get the string contents of a section.
*
* @param string $section
* @param string $default
* @return string
*/
public function yieldContent($section, $default = '')
{
$sectionContent = $default instanceof View ? $default : e($default);
if (isset($this->sections[$section])) {
$sectionContent = $this->sections[$section];
}
$sectionContent = str_replace('@@parent', '--parent--holder--', $sectionContent);
return str_replace(
'--parent--holder--', '@parent', str_replace(static::parentPlaceholder($section), '', $sectionContent)
);
}
/**
* Get the parent placeholder for the current request.
*
* @param string $section
* @return string
*/
public static function parentPlaceholder($section = '')
{
if (! isset(static::$parentPlaceholder[$section])) {
static::$parentPlaceholder[$section] = '##parent-placeholder-'.sha1($section).'##';
}
return static::$parentPlaceholder[$section];
}
/**
* Check if section exists.
*
* @param string $name
* @return bool
*/
public function hasSection($name)
{
return array_key_exists($name, $this->sections);
}
/**
* Get the contents of a section.
*
* @param string $name
* @param string $default
* @return mixed
*/
public function getSection($name, $default = null)
{
return isset($this->getSections()[$name]) ? $this->getSections()[$name] : $default;
}
/**
* Get the entire array of sections.
*
* @return array
*/
public function getSections()
{
return $this->sections;
}
/**
* Flush all of the sections.
*
* @return void
*/
public function flushSections()
{
$this->sections = [];
$this->sectionStack = [];
}
}

View File

@@ -0,0 +1,90 @@
<?php
namespace Illuminate\View\Concerns;
use Countable;
use Illuminate\Support\Arr;
trait ManagesLoops
{
/**
* The stack of in-progress loops.
*
* @var array
*/
protected $loopsStack = [];
/**
* Add new loop to the stack.
*
* @param \Countable|array $data
* @return void
*/
public function addLoop($data)
{
$length = is_array($data) || $data instanceof Countable ? count($data) : null;
$parent = Arr::last($this->loopsStack);
$this->loopsStack[] = [
'iteration' => 0,
'index' => 0,
'remaining' => isset($length) ? $length : null,
'count' => $length,
'first' => true,
'last' => isset($length) ? $length == 1 : null,
'depth' => count($this->loopsStack) + 1,
'parent' => $parent ? (object) $parent : null,
];
}
/**
* Increment the top loop's indices.
*
* @return void
*/
public function incrementLoopIndices()
{
$loop = $this->loopsStack[$index = count($this->loopsStack) - 1];
$this->loopsStack[$index] = array_merge($this->loopsStack[$index], [
'iteration' => $loop['iteration'] + 1,
'index' => $loop['iteration'],
'first' => $loop['iteration'] == 0,
'remaining' => isset($loop['count']) ? $loop['remaining'] - 1 : null,
'last' => isset($loop['count']) ? $loop['iteration'] == $loop['count'] - 1 : null,
]);
}
/**
* Pop a loop from the top of the loop stack.
*
* @return void
*/
public function popLoop()
{
array_pop($this->loopsStack);
}
/**
* Get an instance of the last loop in the stack.
*
* @return \stdClass|null
*/
public function getLastLoop()
{
if ($last = Arr::last($this->loopsStack)) {
return (object) $last;
}
}
/**
* Get the entire loop stack.
*
* @return array
*/
public function getLoopStack()
{
return $this->loopsStack;
}
}

View File

@@ -0,0 +1,177 @@
<?php
namespace Illuminate\View\Concerns;
use InvalidArgumentException;
trait ManagesStacks
{
/**
* All of the finished, captured push sections.
*
* @var array
*/
protected $pushes = [];
/**
* All of the finished, captured prepend sections.
*
* @var array
*/
protected $prepends = [];
/**
* The stack of in-progress push sections.
*
* @var array
*/
protected $pushStack = [];
/**
* Start injecting content into a push section.
*
* @param string $section
* @param string $content
* @return void
*/
public function startPush($section, $content = '')
{
if ($content === '') {
if (ob_start()) {
$this->pushStack[] = $section;
}
} else {
$this->extendPush($section, $content);
}
}
/**
* Stop injecting content into a push section.
*
* @return string
* @throws \InvalidArgumentException
*/
public function stopPush()
{
if (empty($this->pushStack)) {
throw new InvalidArgumentException('Cannot end a push stack without first starting one.');
}
return tap(array_pop($this->pushStack), function ($last) {
$this->extendPush($last, ob_get_clean());
});
}
/**
* Append content to a given push section.
*
* @param string $section
* @param string $content
* @return void
*/
protected function extendPush($section, $content)
{
if (! isset($this->pushes[$section])) {
$this->pushes[$section] = [];
}
if (! isset($this->pushes[$section][$this->renderCount])) {
$this->pushes[$section][$this->renderCount] = $content;
} else {
$this->pushes[$section][$this->renderCount] .= $content;
}
}
/**
* Start prepending content into a push section.
*
* @param string $section
* @param string $content
* @return void
*/
public function startPrepend($section, $content = '')
{
if ($content === '') {
if (ob_start()) {
$this->pushStack[] = $section;
}
} else {
$this->extendPrepend($section, $content);
}
}
/**
* Stop prepending content into a push section.
*
* @return string
* @throws \InvalidArgumentException
*/
public function stopPrepend()
{
if (empty($this->pushStack)) {
throw new InvalidArgumentException('Cannot end a prepend operation without first starting one.');
}
return tap(array_pop($this->pushStack), function ($last) {
$this->extendPrepend($last, ob_get_clean());
});
}
/**
* Prepend content to a given stack.
*
* @param string $section
* @param string $content
* @return void
*/
protected function extendPrepend($section, $content)
{
if (! isset($this->prepends[$section])) {
$this->prepends[$section] = [];
}
if (! isset($this->prepends[$section][$this->renderCount])) {
$this->prepends[$section][$this->renderCount] = $content;
} else {
$this->prepends[$section][$this->renderCount] = $content.$this->prepends[$section][$this->renderCount];
}
}
/**
* Get the string contents of a push section.
*
* @param string $section
* @param string $default
* @return string
*/
public function yieldPushContent($section, $default = '')
{
if (! isset($this->pushes[$section]) && ! isset($this->prepends[$section])) {
return $default;
}
$output = '';
if (isset($this->prepends[$section])) {
$output .= implode(array_reverse($this->prepends[$section]));
}
if (isset($this->pushes[$section])) {
$output .= implode($this->pushes[$section]);
}
return $output;
}
/**
* Flush all of the stacks.
*
* @return void
*/
public function flushStacks()
{
$this->pushes = [];
$this->prepends = [];
$this->pushStack = [];
}
}

View File

@@ -0,0 +1,38 @@
<?php
namespace Illuminate\View\Concerns;
trait ManagesTranslations
{
/**
* The translation replacements for the translation being rendered.
*
* @var array
*/
protected $translationReplacements = [];
/**
* Start a translation block.
*
* @param array $replacements
* @return void
*/
public function startTranslation($replacements = [])
{
ob_start();
$this->translationReplacements = $replacements;
}
/**
* Render the current translation.
*
* @return string
*/
public function renderTranslation()
{
return $this->container->make('translator')->getFromJson(
trim(ob_get_clean()), $this->translationReplacements
);
}
}

View File

@@ -0,0 +1,102 @@
<?php
namespace Illuminate\View\Engines;
use Exception;
use ErrorException;
use Illuminate\View\Compilers\CompilerInterface;
class CompilerEngine extends PhpEngine
{
/**
* The Blade compiler instance.
*
* @var \Illuminate\View\Compilers\CompilerInterface
*/
protected $compiler;
/**
* A stack of the last compiled templates.
*
* @var array
*/
protected $lastCompiled = [];
/**
* Create a new Blade view engine instance.
*
* @param \Illuminate\View\Compilers\CompilerInterface $compiler
* @return void
*/
public function __construct(CompilerInterface $compiler)
{
$this->compiler = $compiler;
}
/**
* Get the evaluated contents of the view.
*
* @param string $path
* @param array $data
* @return string
*/
public function get($path, array $data = [])
{
$this->lastCompiled[] = $path;
// 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)) {
$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);
array_pop($this->lastCompiled);
return $results;
}
/**
* Handle a view exception.
*
* @param \Exception $e
* @param int $obLevel
* @return void
*
* @throws \Exception
*/
protected function handleViewException(Exception $e, $obLevel)
{
$e = new ErrorException($this->getMessage($e), 0, 1, $e->getFile(), $e->getLine(), $e);
parent::handleViewException($e, $obLevel);
}
/**
* Get the exception message for an exception.
*
* @param \Exception $e
* @return string
*/
protected function getMessage(Exception $e)
{
return $e->getMessage().' (View: '.realpath(last($this->lastCompiled)).')';
}
/**
* Get the compiler implementation.
*
* @return \Illuminate\View\Compilers\CompilerInterface
*/
public function getCompiler()
{
return $this->compiler;
}
}

View File

@@ -0,0 +1,23 @@
<?php
namespace Illuminate\View\Engines;
abstract class Engine
{
/**
* The view that was last to be rendered.
*
* @var string
*/
protected $lastRendered;
/**
* Get the last view that was rendered.
*
* @return string
*/
public function getLastRendered()
{
return $this->lastRendered;
}
}

View File

@@ -0,0 +1,15 @@
<?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 = []);
}

View File

@@ -0,0 +1,59 @@
<?php
namespace Illuminate\View\Engines;
use Closure;
use InvalidArgumentException;
class EngineResolver
{
/**
* The array of engine resolvers.
*
* @var array
*/
protected $resolvers = [];
/**
* The resolved engine instances.
*
* @var array
*/
protected $resolved = [];
/**
* Register a new engine resolver.
*
* The engine string typically corresponds to a file extension.
*
* @param string $engine
* @param \Closure $resolver
* @return void
*/
public function register($engine, Closure $resolver)
{
unset($this->resolved[$engine]);
$this->resolvers[$engine] = $resolver;
}
/**
* Resolver an engine instance by name.
*
* @param string $engine
* @return \Illuminate\View\Engines\EngineInterface
* @throws \InvalidArgumentException
*/
public function resolve($engine)
{
if (isset($this->resolved[$engine])) {
return $this->resolved[$engine];
}
if (isset($this->resolvers[$engine])) {
return $this->resolved[$engine] = call_user_func($this->resolvers[$engine]);
}
throw new InvalidArgumentException("Engine $engine not found.");
}
}

View File

@@ -0,0 +1,18 @@
<?php
namespace Illuminate\View\Engines;
class FileEngine implements EngineInterface
{
/**
* Get the evaluated contents of the view.
*
* @param string $path
* @param array $data
* @return string
*/
public function get($path, array $data = [])
{
return file_get_contents($path);
}
}

View File

@@ -0,0 +1,69 @@
<?php
namespace Illuminate\View\Engines;
use Exception;
use Throwable;
use Symfony\Component\Debug\Exception\FatalThrowableError;
class PhpEngine implements EngineInterface
{
/**
* Get the evaluated contents of the view.
*
* @param string $path
* @param array $data
* @return string
*/
public function get($path, array $data = [])
{
return $this->evaluatePath($path, $data);
}
/**
* Get the evaluated contents of the view at the given path.
*
* @param string $__path
* @param array $__data
* @return string
*/
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);
} catch (Throwable $e) {
$this->handleViewException(new FatalThrowableError($e), $obLevel);
}
return ltrim(ob_get_clean());
}
/**
* Handle a view exception.
*
* @param \Exception $e
* @param int $obLevel
* @return void
*
* @throws \Exception
*/
protected function handleViewException(Exception $e, $obLevel)
{
while (ob_get_level() > $obLevel) {
ob_end_clean();
}
throw $e;
}
}

View File

@@ -0,0 +1,542 @@
<?php
namespace Illuminate\View;
use Illuminate\Support\Arr;
use Illuminate\Support\Str;
use InvalidArgumentException;
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;
class Factory implements FactoryContract
{
use Concerns\ManagesComponents,
Concerns\ManagesEvents,
Concerns\ManagesLayouts,
Concerns\ManagesLoops,
Concerns\ManagesStacks,
Concerns\ManagesTranslations;
/**
* The engine implementation.
*
* @var \Illuminate\View\Engines\EngineResolver
*/
protected $engines;
/**
* The view finder implementation.
*
* @var \Illuminate\View\ViewFinderInterface
*/
protected $finder;
/**
* The event dispatcher instance.
*
* @var \Illuminate\Contracts\Events\Dispatcher
*/
protected $events;
/**
* The IoC container instance.
*
* @var \Illuminate\Contracts\Container\Container
*/
protected $container;
/**
* Data that should be available to all templates.
*
* @var array
*/
protected $shared = [];
/**
* The extension to engine bindings.
*
* @var array
*/
protected $extensions = [
'blade.php' => 'blade',
'php' => 'php',
'css' => 'file',
];
/**
* The view composer events.
*
* @var array
*/
protected $composers = [];
/**
* The number of active rendering operations.
*
* @var int
*/
protected $renderCount = 0;
/**
* Create a new view factory instance.
*
* @param \Illuminate\View\Engines\EngineResolver $engines
* @param \Illuminate\View\ViewFinderInterface $finder
* @param \Illuminate\Contracts\Events\Dispatcher $events
* @return void
*/
public function __construct(EngineResolver $engines, ViewFinderInterface $finder, Dispatcher $events)
{
$this->finder = $finder;
$this->events = $events;
$this->engines = $engines;
$this->share('__env', $this);
}
/**
* Get the evaluated view contents for the given view.
*
* @param string $path
* @param array $data
* @param array $mergeData
* @return \Illuminate\Contracts\View\View
*/
public function file($path, $data = [], $mergeData = [])
{
$data = array_merge($mergeData, $this->parseData($data));
return tap($this->viewInstance($path, $path, $data), function ($view) {
$this->callCreator($view);
});
}
/**
* Get the evaluated view contents for the given view.
*
* @param string $view
* @param array $data
* @param array $mergeData
* @return \Illuminate\Contracts\View\View
*/
public function make($view, $data = [], $mergeData = [])
{
$path = $this->finder->find(
$view = $this->normalizeName($view)
);
// Next, we will create the view instance and call the view creator for the view
// which can set any data, etc. Then we will return the view instance back to
// the caller for rendering or performing other view manipulations on this.
$data = array_merge($mergeData, $this->parseData($data));
return tap($this->viewInstance($view, $path, $data), function ($view) {
$this->callCreator($view);
});
}
/**
* Get the rendered content of the view based on a given condition.
*
* @param bool $condition
* @param string $view
* @param array $data
* @param array $mergeData
* @return string
*/
public function renderWhen($condition, $view, $data = [], $mergeData = [])
{
if (! $condition) {
return '';
}
return $this->make($view, $this->parseData($data), $mergeData)->render();
}
/**
* Get the rendered contents of a partial from a loop.
*
* @param string $view
* @param array $data
* @param string $iterator
* @param string $empty
* @return string
*/
public function renderEach($view, $data, $iterator, $empty = 'raw|')
{
$result = '';
// If is actually data in the array, we will loop through the data and append
// an instance of the partial view to the final result HTML passing in the
// iterated value of this data array, allowing the views to access them.
if (count($data) > 0) {
foreach ($data as $key => $value) {
$result .= $this->make(
$view, ['key' => $key, $iterator => $value]
)->render();
}
}
// If there is no data in the array, we will render the contents of the empty
// 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|')
? substr($empty, 4)
: $this->make($empty)->render();
}
return $result;
}
/**
* Normalize a view name.
*
* @param string $name
* @return string
*/
protected function normalizeName($name)
{
return ViewName::normalize($name);
}
/**
* Parse the given data into a raw array.
*
* @param mixed $data
* @return array
*/
protected function parseData($data)
{
return $data instanceof Arrayable ? $data->toArray() : $data;
}
/**
* Create a new view instance from the given arguments.
*
* @param string $view
* @param string $path
* @param array $data
* @return \Illuminate\Contracts\View\View
*/
protected function viewInstance($view, $path, $data)
{
return new View($this, $this->getEngineFromPath($path), $view, $path, $data);
}
/**
* Determine if a given view exists.
*
* @param string $view
* @return bool
*/
public function exists($view)
{
try {
$this->finder->find($view);
} catch (InvalidArgumentException $e) {
return false;
}
return true;
}
/**
* Get the appropriate view engine for the given path.
*
* @param string $path
* @return \Illuminate\View\Engines\EngineInterface
*
* @throws \InvalidArgumentException
*/
public function getEngineFromPath($path)
{
if (! $extension = $this->getExtension($path)) {
throw new InvalidArgumentException("Unrecognized extension in file: $path");
}
$engine = $this->extensions[$extension];
return $this->engines->resolve($engine);
}
/**
* Get the extension used by the view file.
*
* @param string $path
* @return string
*/
protected function getExtension($path)
{
$extensions = array_keys($this->extensions);
return Arr::first($extensions, function ($value) use ($path) {
return Str::endsWith($path, '.'.$value);
});
}
/**
* Add a piece of shared data to the environment.
*
* @param array|string $key
* @param mixed $value
* @return mixed
*/
public function share($key, $value = null)
{
$keys = is_array($key) ? $key : [$key => $value];
foreach ($keys as $key => $value) {
$this->shared[$key] = $value;
}
return $value;
}
/**
* Increment the rendering counter.
*
* @return void
*/
public function incrementRender()
{
$this->renderCount++;
}
/**
* Decrement the rendering counter.
*
* @return void
*/
public function decrementRender()
{
$this->renderCount--;
}
/**
* Check if there are no active render operations.
*
* @return bool
*/
public function doneRendering()
{
return $this->renderCount == 0;
}
/**
* Add a location to the array of view locations.
*
* @param string $location
* @return void
*/
public function addLocation($location)
{
$this->finder->addLocation($location);
}
/**
* Add a new namespace to the loader.
*
* @param string $namespace
* @param string|array $hints
* @return $this
*/
public function addNamespace($namespace, $hints)
{
$this->finder->addNamespace($namespace, $hints);
return $this;
}
/**
* Prepend a new namespace to the loader.
*
* @param string $namespace
* @param string|array $hints
* @return $this
*/
public function prependNamespace($namespace, $hints)
{
$this->finder->prependNamespace($namespace, $hints);
return $this;
}
/**
* Replace the namespace hints for the given namespace.
*
* @param string $namespace
* @param string|array $hints
* @return $this
*/
public function replaceNamespace($namespace, $hints)
{
$this->finder->replaceNamespace($namespace, $hints);
return $this;
}
/**
* Register a valid view extension and its engine.
*
* @param string $extension
* @param string $engine
* @param \Closure $resolver
* @return void
*/
public function addExtension($extension, $engine, $resolver = null)
{
$this->finder->addExtension($extension);
if (isset($resolver)) {
$this->engines->register($engine, $resolver);
}
unset($this->extensions[$extension]);
$this->extensions = array_merge([$extension => $engine], $this->extensions);
}
/**
* Flush all of the factory state like sections and stacks.
*
* @return void
*/
public function flushState()
{
$this->renderCount = 0;
$this->flushSections();
$this->flushStacks();
}
/**
* Flush all of the section contents if done rendering.
*
* @return void
*/
public function flushStateIfDoneRendering()
{
if ($this->doneRendering()) {
$this->flushState();
}
}
/**
* Get the extension to engine bindings.
*
* @return array
*/
public function getExtensions()
{
return $this->extensions;
}
/**
* Get the engine resolver instance.
*
* @return \Illuminate\View\Engines\EngineResolver
*/
public function getEngineResolver()
{
return $this->engines;
}
/**
* Get the view finder instance.
*
* @return \Illuminate\View\ViewFinderInterface
*/
public function getFinder()
{
return $this->finder;
}
/**
* Set the view finder instance.
*
* @param \Illuminate\View\ViewFinderInterface $finder
* @return void
*/
public function setFinder(ViewFinderInterface $finder)
{
$this->finder = $finder;
}
/**
* Flush the cache of views located by the finder.
*
* @return void
*/
public function flushFinderCache()
{
$this->getFinder()->flush();
}
/**
* Get the event dispatcher instance.
*
* @return \Illuminate\Contracts\Events\Dispatcher
*/
public function getDispatcher()
{
return $this->events;
}
/**
* Set the event dispatcher instance.
*
* @param \Illuminate\Contracts\Events\Dispatcher $events
* @return void
*/
public function setDispatcher(Dispatcher $events)
{
$this->events = $events;
}
/**
* Get the IoC container instance.
*
* @return \Illuminate\Contracts\Container\Container
*/
public function getContainer()
{
return $this->container;
}
/**
* Set the IoC container instance.
*
* @param \Illuminate\Contracts\Container\Container $container
* @return void
*/
public function setContainer(Container $container)
{
$this->container = $container;
}
/**
* Get an item from the shared data.
*
* @param string $key
* @param mixed $default
* @return mixed
*/
public function shared($key, $default = null)
{
return Arr::get($this->shared, $key, $default);
}
/**
* Get all of the shared data for the environment.
*
* @return array
*/
public function getShared()
{
return $this->shared;
}
}

View File

@@ -0,0 +1,298 @@
<?php
namespace Illuminate\View;
use InvalidArgumentException;
use Illuminate\Filesystem\Filesystem;
class FileViewFinder implements ViewFinderInterface
{
/**
* The filesystem instance.
*
* @var \Illuminate\Filesystem\Filesystem
*/
protected $files;
/**
* The array of active view paths.
*
* @var array
*/
protected $paths;
/**
* The array of views that have been located.
*
* @var array
*/
protected $views = [];
/**
* The namespace to file path hints.
*
* @var array
*/
protected $hints = [];
/**
* Register a view extension with the finder.
*
* @var array
*/
protected $extensions = ['blade.php', 'php', 'css'];
/**
* Create a new file view loader instance.
*
* @param \Illuminate\Filesystem\Filesystem $files
* @param array $paths
* @param array $extensions
* @return void
*/
public function __construct(Filesystem $files, array $paths, array $extensions = null)
{
$this->files = $files;
$this->paths = $paths;
if (isset($extensions)) {
$this->extensions = $extensions;
}
}
/**
* Get the fully qualified location of the view.
*
* @param string $name
* @return string
*/
public function find($name)
{
if (isset($this->views[$name])) {
return $this->views[$name];
}
if ($this->hasHintInformation($name = trim($name))) {
return $this->views[$name] = $this->findNamespacedView($name);
}
return $this->views[$name] = $this->findInPaths($name, $this->paths);
}
/**
* Get the path to a template with a named path.
*
* @param string $name
* @return string
*/
protected function findNamespacedView($name)
{
list($namespace, $view) = $this->parseNamespaceSegments($name);
return $this->findInPaths($view, $this->hints[$namespace]);
}
/**
* Get the segments of a template with a named path.
*
* @param string $name
* @return array
*
* @throws \InvalidArgumentException
*/
protected function parseNamespaceSegments($name)
{
$segments = explode(static::HINT_PATH_DELIMITER, $name);
if (count($segments) != 2) {
throw new InvalidArgumentException("View [$name] has an invalid name.");
}
if (! isset($this->hints[$segments[0]])) {
throw new InvalidArgumentException("No hint path defined for [{$segments[0]}].");
}
return $segments;
}
/**
* Find the given view in the list of paths.
*
* @param string $name
* @param array $paths
* @return string
*
* @throws \InvalidArgumentException
*/
protected function findInPaths($name, $paths)
{
foreach ((array) $paths as $path) {
foreach ($this->getPossibleViewFiles($name) as $file) {
if ($this->files->exists($viewPath = $path.'/'.$file)) {
return $viewPath;
}
}
}
throw new InvalidArgumentException("View [$name] not found.");
}
/**
* Get an array of possible view files.
*
* @param string $name
* @return array
*/
protected function getPossibleViewFiles($name)
{
return array_map(function ($extension) use ($name) {
return str_replace('.', '/', $name).'.'.$extension;
}, $this->extensions);
}
/**
* Add a location to the finder.
*
* @param string $location
* @return void
*/
public function addLocation($location)
{
$this->paths[] = $location;
}
/**
* Prepend a location to the finder.
*
* @param string $location
* @return void
*/
public function prependLocation($location)
{
array_unshift($this->paths, $location);
}
/**
* Add a namespace hint to the finder.
*
* @param string $namespace
* @param string|array $hints
* @return void
*/
public function addNamespace($namespace, $hints)
{
$hints = (array) $hints;
if (isset($this->hints[$namespace])) {
$hints = array_merge($this->hints[$namespace], $hints);
}
$this->hints[$namespace] = $hints;
}
/**
* Prepend a namespace hint to the finder.
*
* @param string $namespace
* @param string|array $hints
* @return void
*/
public function prependNamespace($namespace, $hints)
{
$hints = (array) $hints;
if (isset($this->hints[$namespace])) {
$hints = array_merge($hints, $this->hints[$namespace]);
}
$this->hints[$namespace] = $hints;
}
/**
* Replace the namespace hints for the given namespace.
*
* @param string $namespace
* @param string|array $hints
* @return void
*/
public function replaceNamespace($namespace, $hints)
{
$this->hints[$namespace] = (array) $hints;
}
/**
* Register an extension with the view finder.
*
* @param string $extension
* @return void
*/
public function addExtension($extension)
{
if (($index = array_search($extension, $this->extensions)) !== false) {
unset($this->extensions[$index]);
}
array_unshift($this->extensions, $extension);
}
/**
* Returns whether or not the view name has any hint information.
*
* @param string $name
* @return bool
*/
public function hasHintInformation($name)
{
return strpos($name, static::HINT_PATH_DELIMITER) > 0;
}
/**
* Flush the cache of located views.
*
* @return void
*/
public function flush()
{
$this->views = [];
}
/**
* Get the filesystem instance.
*
* @return \Illuminate\Filesystem\Filesystem
*/
public function getFilesystem()
{
return $this->files;
}
/**
* Get the active view paths.
*
* @return array
*/
public function getPaths()
{
return $this->paths;
}
/**
* Get the namespace to file path hints.
*
* @return array
*/
public function getHints()
{
return $this->hints;
}
/**
* Get registered extensions.
*
* @return array
*/
public function getExtensions()
{
return $this->extensions;
}
}

View File

@@ -0,0 +1,51 @@
<?php
namespace Illuminate\View\Middleware;
use Closure;
use Illuminate\Support\ViewErrorBag;
use Illuminate\Contracts\View\Factory as ViewFactory;
class ShareErrorsFromSession
{
/**
* The view factory implementation.
*
* @var \Illuminate\Contracts\View\Factory
*/
protected $view;
/**
* Create a new error binder instance.
*
* @param \Illuminate\Contracts\View\Factory $view
* @return void
*/
public function __construct(ViewFactory $view)
{
$this->view = $view;
}
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
// If the current session has an "errors" variable bound to it, we will share
// its value with all view instances so the views can easily access errors
// without having to bind. An empty bag is set when there aren't errors.
$this->view->share(
'errors', $request->session()->get('errors') ?: new ViewErrorBag
);
// Putting the errors in the view for every view allows the developer to just
// assume that some errors are always available, which is convenient since
// they don't have to continually run checks for the presence of errors.
return $next($request);
}
}

View File

@@ -0,0 +1,414 @@
<?php
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\MessageProvider;
use Illuminate\Contracts\View\View as ViewContract;
class View implements ArrayAccess, ViewContract
{
/**
* The view factory instance.
*
* @var \Illuminate\View\Factory
*/
protected $factory;
/**
* The engine implementation.
*
* @var \Illuminate\View\Engines\EngineInterface
*/
protected $engine;
/**
* The name of the view.
*
* @var string
*/
protected $view;
/**
* The array of view data.
*
* @var array
*/
protected $data;
/**
* The path to the view file.
*
* @var string
*/
protected $path;
/**
* Create a new view instance.
*
* @param \Illuminate\View\Factory $factory
* @param \Illuminate\View\Engines\EngineInterface $engine
* @param string $view
* @param string $path
* @param mixed $data
* @return void
*/
public function __construct(Factory $factory, EngineInterface $engine, $view, $path, $data = [])
{
$this->view = $view;
$this->path = $path;
$this->engine = $engine;
$this->factory = $factory;
$this->data = $data instanceof Arrayable ? $data->toArray() : (array) $data;
}
/**
* Get the string contents of the view.
*
* @param callable|null $callback
* @return string
*
* @throws \Throwable
*/
public function render(callable $callback = null)
{
try {
$contents = $this->renderContents();
$response = isset($callback) ? call_user_func($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
// another view gets rendered in the future by the application developer.
$this->factory->flushStateIfDoneRendering();
return ! is_null($response) ? $response : $contents;
} catch (Exception $e) {
$this->factory->flushState();
throw $e;
} catch (Throwable $e) {
$this->factory->flushState();
throw $e;
}
}
/**
* Get the contents of the view instance.
*
* @return string
*/
protected function renderContents()
{
// We will keep track of the amount 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();
$this->factory->callComposer($this);
$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
// no old sections are staying around in the memory of an environment.
$this->factory->decrementRender();
return $contents;
}
/**
* Get the evaluated contents of the view.
*
* @return string
*/
protected function getContents()
{
return $this->engine->get($this->path, $this->gatherData());
}
/**
* Get the data bound to the view instance.
*
* @return array
*/
protected function gatherData()
{
$data = array_merge($this->factory->getShared(), $this->data);
foreach ($data as $key => $value) {
if ($value instanceof Renderable) {
$data[$key] = $value->render();
}
}
return $data;
}
/**
* Get the sections of the rendered view.
*
* @return array
*/
public function renderSections()
{
return $this->render(function () {
return $this->factory->getSections();
});
}
/**
* Add a piece of data to the view.
*
* @param string|array $key
* @param mixed $value
* @return $this
*/
public function with($key, $value = null)
{
if (is_array($key)) {
$this->data = array_merge($this->data, $key);
} else {
$this->data[$key] = $value;
}
return $this;
}
/**
* Add a view instance to the view data.
*
* @param string $key
* @param string $view
* @param array $data
* @return $this
*/
public function nest($key, $view, array $data = [])
{
return $this->with($key, $this->factory->make($view, $data));
}
/**
* Add validation errors to the view.
*
* @param \Illuminate\Contracts\Support\MessageProvider|array $provider
* @return $this
*/
public function withErrors($provider)
{
$this->with('errors', $this->formatErrors($provider));
return $this;
}
/**
* Format the given message provider into a MessageBag.
*
* @param \Illuminate\Contracts\Support\MessageProvider|array $provider
* @return \Illuminate\Support\MessageBag
*/
protected function formatErrors($provider)
{
return $provider instanceof MessageProvider
? $provider->getMessageBag() : new MessageBag((array) $provider);
}
/**
* Get the name of the view.
*
* @return string
*/
public function name()
{
return $this->getName();
}
/**
* Get the name of the view.
*
* @return string
*/
public function getName()
{
return $this->view;
}
/**
* Get the array of view data.
*
* @return array
*/
public function getData()
{
return $this->data;
}
/**
* Get the path to the view file.
*
* @return string
*/
public function getPath()
{
return $this->path;
}
/**
* Set the path to the view.
*
* @param string $path
* @return void
*/
public function setPath($path)
{
$this->path = $path;
}
/**
* Get the view factory instance.
*
* @return \Illuminate\View\Factory
*/
public function getFactory()
{
return $this->factory;
}
/**
* Get the view's rendering engine.
*
* @return \Illuminate\View\Engines\EngineInterface
*/
public function getEngine()
{
return $this->engine;
}
/**
* Determine if a piece of data is bound.
*
* @param string $key
* @return bool
*/
public function offsetExists($key)
{
return array_key_exists($key, $this->data);
}
/**
* Get a piece of bound data to the view.
*
* @param string $key
* @return mixed
*/
public function offsetGet($key)
{
return $this->data[$key];
}
/**
* Set a piece of data on the view.
*
* @param string $key
* @param mixed $value
* @return void
*/
public function offsetSet($key, $value)
{
$this->with($key, $value);
}
/**
* Unset a piece of data from the view.
*
* @param string $key
* @return void
*/
public function offsetUnset($key)
{
unset($this->data[$key]);
}
/**
* Get a piece of data from the view.
*
* @param string $key
* @return mixed
*/
public function &__get($key)
{
return $this->data[$key];
}
/**
* Set a piece of data on the view.
*
* @param string $key
* @param mixed $value
* @return void
*/
public function __set($key, $value)
{
$this->with($key, $value);
}
/**
* Check if a piece of data is bound to the view.
*
* @param string $key
* @return bool
*/
public function __isset($key)
{
return isset($this->data[$key]);
}
/**
* Remove a piece of bound data from the view.
*
* @param string $key
* @return bool
*/
public function __unset($key)
{
unset($this->data[$key]);
}
/**
* Dynamically bind parameters to the view.
*
* @param string $method
* @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.");
}
return $this->with(Str::snake(substr($method, 4)), $parameters[0]);
}
/**
* Get the string contents of the view.
*
* @return string
*/
public function __toString()
{
return $this->render();
}
}

View File

@@ -0,0 +1,71 @@
<?php
namespace Illuminate\View;
interface ViewFinderInterface
{
/**
* Hint path delimiter value.
*
* @var string
*/
const HINT_PATH_DELIMITER = '::';
/**
* Get the fully qualified location of the view.
*
* @param string $view
* @return string
*/
public function find($view);
/**
* Add a location to the finder.
*
* @param string $location
* @return void
*/
public function addLocation($location);
/**
* Add a namespace hint to the finder.
*
* @param string $namespace
* @param string|array $hints
* @return void
*/
public function addNamespace($namespace, $hints);
/**
* Prepend a namespace hint to the finder.
*
* @param string $namespace
* @param string|array $hints
* @return void
*/
public function prependNamespace($namespace, $hints);
/**
* Replace the namespace hints for the given namespace.
*
* @param string $namespace
* @param string|array $hints
* @return $this
*/
public function replaceNamespace($namespace, $hints);
/**
* Add a valid view extension to the finder.
*
* @param string $extension
* @return void
*/
public function addExtension($extension);
/**
* Flush the cache of located views.
*
* @return void
*/
public function flush();
}

View File

@@ -0,0 +1,25 @@
<?php
namespace Illuminate\View;
class ViewName
{
/**
* Normalize the given event name.
*
* @param string $name
* @return string
*/
public static function normalize($name)
{
$delimiter = ViewFinderInterface::HINT_PATH_DELIMITER;
if (strpos($name, $delimiter) === false) {
return str_replace('/', '.', $name);
}
list($namespace, $name) = explode($delimiter, $name);
return $namespace.$delimiter.str_replace('/', '.', $name);
}
}

View File

@@ -0,0 +1,136 @@
<?php
namespace Illuminate\View;
use Illuminate\View\Engines\PhpEngine;
use Illuminate\Support\ServiceProvider;
use Illuminate\View\Engines\FileEngine;
use Illuminate\View\Engines\CompilerEngine;
use Illuminate\View\Engines\EngineResolver;
use Illuminate\View\Compilers\BladeCompiler;
class ViewServiceProvider extends ServiceProvider
{
/**
* Register the service provider.
*
* @return void
*/
public function register()
{
$this->registerFactory();
$this->registerViewFinder();
$this->registerEngineResolver();
}
/**
* Register the view environment.
*
* @return void
*/
public function registerFactory()
{
$this->app->singleton('view', function ($app) {
// Next we need to grab the engine resolver instance that will be used by the
// environment. The resolver will be used by an environment to get each of
// the various engine implementations such as plain PHP or Blade engine.
$resolver = $app['view.engine.resolver'];
$finder = $app['view.finder'];
$env = new Factory($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);
$env->share('app', $app);
return $env;
});
}
/**
* Register the view finder implementation.
*
* @return void
*/
public function registerViewFinder()
{
$this->app->bind('view.finder', function ($app) {
return new FileViewFinder($app['files'], $app['config']['view.paths']);
});
}
/**
* Register the engine resolver instance.
*
* @return void
*/
public function registerEngineResolver()
{
$this->app->singleton('view.engine.resolver', function () {
$resolver = new EngineResolver;
// Next, we will register the various view engines with the resolver so that the
// environment will resolve the engines needed for various views based on the
// extension of view file. We call a method for each of the view's engines.
foreach (['file', 'php', 'blade'] as $engine) {
$this->{'register'.ucfirst($engine).'Engine'}($resolver);
}
return $resolver;
});
}
/**
* Register the file engine implementation.
*
* @param \Illuminate\View\Engines\EngineResolver $resolver
* @return void
*/
public function registerFileEngine($resolver)
{
$resolver->register('file', function () {
return new FileEngine;
});
}
/**
* Register the PHP engine implementation.
*
* @param \Illuminate\View\Engines\EngineResolver $resolver
* @return void
*/
public function registerPhpEngine($resolver)
{
$resolver->register('php', function () {
return new PhpEngine;
});
}
/**
* Register the Blade engine implementation.
*
* @param \Illuminate\View\Engines\EngineResolver $resolver
* @return void
*/
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']);
});
}
}

View File

@@ -0,0 +1,39 @@
{
"name": "illuminate/view",
"description": "The Illuminate View package.",
"license": "MIT",
"homepage": "https://laravel.com",
"support": {
"issues": "https://github.com/laravel/framework/issues",
"source": "https://github.com/laravel/framework"
},
"authors": [
{
"name": "Taylor Otwell",
"email": "taylor@laravel.com"
}
],
"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"
},
"autoload": {
"psr-4": {
"Illuminate\\View\\": ""
}
},
"extra": {
"branch-alias": {
"dev-master": "5.4-dev"
}
},
"config": {
"sort-packages": true
},
"minimum-stability": "dev"
}