Compilers/BladeCompiler.php000064400000031354150145556170011733 0ustar00setPath($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) { if (strpos($value, '@verbatim') !== false) { $value = $this->storeVerbatimBlocks($value); } $this->footer = []; if (strpos($value, '@php') !== false) { $value = $this->storePhpBlocks($value); } $result = ''; // 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->rawBlocks)) { $result = $this->restoreRawContent($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('/(?storeRawBlock($matches[1]); }, $value); } /** * Store the PHP blocks and replace them with a temporary placeholder. * * @param string $value * @return string */ protected function storePhpBlocks($value) { return preg_replace_callback('/(?storeRawBlock(""); }, $value); } /** * Store a raw block and return a unique raw placeholder. * * @param string $value * @return string */ protected function storeRawBlock($value) { return $this->getRawPlaceholder( array_push($this->rawBlocks, $value) - 1 ); } /** * Replace the raw placeholders with the original code stored in the raw blocks. * * @param string $result * @return string */ protected function restoreRawContent($result) { $result = preg_replace_callback('/'.$this->getRawPlaceholder('(\d+)').'/', function ($matches) { return $this->rawBlocks[$matches[1]]; }, $result); $this->rawBlocks = []; return $result; } /** * Get a placeholder to temporary mark the position of raw blocks. * * @param int|string $replace * @return string */ protected function getRawPlaceholder($replace) { return str_replace('#', $replace, '@__raw_block_#__@'); } /** * Add the stored footers onto the given content. * * @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 an "if" statement directive. * * @param string $name * @param callable $callback * @return void */ public function if($name, callable $callback) { $this->conditions[$name] = $callback; $this->directive($name, function ($expression) use ($name) { return $expression ? "" : ""; }); $this->directive('else'.$name, function ($expression) use ($name) { return $expression ? "" : ""; }); $this->directive('end'.$name, function () { return ''; }); } /** * Check the result of a condition. * * @param string $name * @param array $parameters * @return bool */ public function check($name, ...$parameters) { return call_user_func($this->conditions[$name], ...$parameters); } /** * Register a component alias directive. * * @param string $path * @param string $alias * @return void */ public function component($path, $alias = null) { $alias = $alias ?: array_last(explode('.', $path)); $this->directive($alias, function ($expression) use ($path) { return $expression ? "startComponent('{$path}', {$expression}); ?>" : "startComponent('{$path}'); ?>"; }); $this->directive('end'.$alias, function ($expression) { return 'renderComponent(); ?>'; }); } /** * Register an include alias directive. * * @param string $path * @param string $alias * @return void */ public function include($path, $alias = null) { $alias = $alias ?: array_last(explode('.', $path)); $this->directive($alias, function ($expression) use ($path) { $expression = $this->stripParentheses($expression) ?: '[]'; return "make('{$path}', {$expression}, array_except(get_defined_vars(), array('__data', '__path')))->render(); ?>"; }); } /** * 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; } /** * Set the "echo" format to double encode entities. * * @return void */ public function withDoubleEncoding() { $this->setEchoFormat('e(%s, true)'); } /** * Set the "echo" format to not double encode entities. * * @return void */ public function withoutDoubleEncoding() { $this->setEchoFormat('e(%s, false)'); } } Compilers/Compiler.php000075500000003405150145556170011002 0ustar00files = $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); } } Compilers/CompilerInterface.php000075500000001060150145556170012616 0ustar00check{$expression}): ?>"; } /** * Compile the cannot statements into valid PHP. * * @param string $expression * @return string */ protected function compileCannot($expression) { return "denies{$expression}): ?>"; } /** * Compile the else-can statements into valid PHP. * * @param string $expression * @return string */ protected function compileElsecan($expression) { return "check{$expression}): ?>"; } /** * Compile the else-cannot statements into valid PHP. * * @param string $expression * @return string */ protected function compileElsecannot($expression) { return "denies{$expression}): ?>"; } /** * Compile the end-can statements into valid PHP. * * @return string */ protected function compileEndcan() { return ''; } /** * Compile the end-cannot statements into valid PHP. * * @return string */ protected function compileEndcannot() { return ''; } } Compilers/Concerns/CompilesComments.php000064400000000635150145556170014262 0ustar00contentTags[0], $this->contentTags[1]); return preg_replace($pattern, '', $value); } } Compilers/Concerns/CompilesComponents.php000064400000001771150145556170014624 0ustar00startComponent{$expression}; ?>"; } /** * Compile the end-component statements into valid PHP. * * @return string */ protected function compileEndComponent() { return 'renderComponent(); ?>'; } /** * Compile the slot statements into valid PHP. * * @param string $expression * @return string */ protected function compileSlot($expression) { return "slot{$expression}; ?>"; } /** * Compile the end-slot statements into valid PHP. * * @return string */ protected function compileEndSlot() { return 'endSlot(); ?>'; } } Compilers/Concerns/CompilesConditionals.php000064400000010277150145556170015126 0ustar00guard{$guard}->check()): ?>"; } /** * Compile the end-auth statements into valid PHP. * * @return string */ protected function compileEndAuth() { return ''; } /** * 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 "guard{$guard}->guest()): ?>"; } /** * Compile the end-guest statements into valid PHP. * * @return string */ protected function compileEndGuest() { return ''; } /** * Compile the has-section statements into valid PHP. * * @param string $expression * @return string */ protected function compileHasSection($expression) { return "yieldContent{$expression}))): ?>"; } /** * Compile the if statements into valid PHP. * * @param string $expression * @return string */ protected function compileIf($expression) { return ""; } /** * Compile the unless statements into valid PHP. * * @param string $expression * @return string */ protected function compileUnless($expression) { return ""; } /** * Compile the else-if statements into valid PHP. * * @param string $expression * @return string */ protected function compileElseif($expression) { return ""; } /** * Compile the else statements into valid PHP. * * @return string */ protected function compileElse() { return ''; } /** * Compile the end-if statements into valid PHP. * * @return string */ protected function compileEndif() { return ''; } /** * Compile the end-unless statements into valid PHP. * * @return string */ protected function compileEndunless() { return ''; } /** * Compile the if-isset statements into valid PHP. * * @param string $expression * @return string */ protected function compileIsset($expression) { return ""; } /** * Compile the end-isset statements into valid PHP. * * @return string */ protected function compileEndIsset() { return ''; } /** * Compile the switch statements into valid PHP. * * @param string $expression * @return string */ protected function compileSwitch($expression) { $this->firstCaseInSwitch = true; return "firstCaseInSwitch) { $this->firstCaseInSwitch = false; return "case {$expression}: ?>"; } return ""; } /** * Compile the default statements in switch case into valid PHP. * * @return string */ protected function compileDefault() { return ''; } /** * Compile the end switch statements into valid PHP. * * @return string */ protected function compileEndSwitch() { return ''; } } Compilers/Concerns/CompilesEchos.php000064400000005475150145556170013545 0ustar00getEchoMethods() 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) : "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) : "{$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] : "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+)(.+?)$/si', 'isset($1) ? $1 : $2', $value); } } Compilers/Concerns/CompilesHelpers.php000064400000001351150145556170014073 0ustar00'; } /** * Compile the "dd" statements into valid PHP. * * @param string $arguments * @return string */ protected function compileDd($arguments) { return ""; } /** * Compile the method statements into valid PHP. * * @param string $method * @return string */ protected function compileMethod($method) { return ""; } } Compilers/Concerns/CompilesIncludes.php000064400000003652150145556170014245 0ustar00renderEach{$expression}; ?>"; } /** * Compile the include statements into valid PHP. * * @param string $expression * @return string */ protected function compileInclude($expression) { $expression = $this->stripParentheses($expression); return "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 "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 "renderWhen($expression, array_except(get_defined_vars(), array('__data', '__path'))); ?>"; } /** * Compile the include-first statements into valid PHP. * * @param string $expression * @return string */ protected function compileIncludeFirst($expression) { $expression = $this->stripParentheses($expression); return "first({$expression}, array_except(get_defined_vars(), array('__data', '__path')))->render(); ?>"; } } Compilers/Concerns/CompilesInjections.php000064400000000771150145556170014603 0ustar00"; } } Compilers/Concerns/CompilesJson.php000064400000001325150145556170013403 0ustar00stripParentheses($expression)); $options = isset($parts[1]) ? trim($parts[1]) : $this->encodingOptions; $depth = isset($parts[2]) ? trim($parts[2]) : 512; return ""; } } Compilers/Concerns/CompilesLayouts.php000064400000004732150145556170014137 0ustar00stripParentheses($expression); $echo = "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 "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 "yieldContent{$expression}; ?>"; } /** * Compile the show statements into valid PHP. * * @return string */ protected function compileShow() { return 'yieldSection(); ?>'; } /** * Compile the append statements into valid PHP. * * @return string */ protected function compileAppend() { return 'appendSection(); ?>'; } /** * Compile the overwrite statements into valid PHP. * * @return string */ protected function compileOverwrite() { return 'stopSection(true); ?>'; } /** * Compile the stop statements into valid PHP. * * @return string */ protected function compileStop() { return 'stopSection(); ?>'; } /** * Compile the end-section statements into valid PHP. * * @return string */ protected function compileEndsection() { return 'stopSection(); ?>'; } } Compilers/Concerns/CompilesLoops.php000064400000010536150145556170013572 0ustar00forElseCounter; 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 ""; } /** * Compile the for-else-empty and empty statements into valid PHP. * * @param string $expression * @return string */ protected function compileEmpty($expression) { if ($expression) { return ""; } $empty = '$__empty_'.$this->forElseCounter--; return "popLoop(); \$loop = \$__env->getLastLoop(); if ({$empty}): ?>"; } /** * Compile the end-for-else statements into valid PHP. * * @return string */ protected function compileEndforelse() { return ''; } /** * Compile the end-empty statements into valid PHP. * * @return string */ protected function compileEndEmpty() { return ''; } /** * Compile the for statements into valid PHP. * * @param string $expression * @return string */ protected function compileFor($expression) { return ""; } /** * 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 ""; } /** * 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 ? '' : ""; } return ''; } /** * 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 ? '' : ""; } return ''; } /** * Compile the end-for statements into valid PHP. * * @return string */ protected function compileEndfor() { return ''; } /** * Compile the end-for-each statements into valid PHP. * * @return string */ protected function compileEndforeach() { return 'popLoop(); $loop = $__env->getLastLoop(); ?>'; } /** * Compile the while statements into valid PHP. * * @param string $expression * @return string */ protected function compileWhile($expression) { return ""; } /** * Compile the end-while statements into valid PHP. * * @return string */ protected function compileEndwhile() { return ''; } } Compilers/Concerns/CompilesRawPhp.php000064400000001154150145556170013673 0ustar00"; } return '@php'; } /** * Compile the unset statements into valid PHP. * * @param string $expression * @return string */ protected function compileUnset($expression) { return ""; } } Compilers/Concerns/CompilesStacks.php000064400000002364150145556170013726 0ustar00yieldPushContent{$expression}; ?>"; } /** * Compile the push statements into valid PHP. * * @param string $expression * @return string */ protected function compilePush($expression) { return "startPush{$expression}; ?>"; } /** * Compile the end-push statements into valid PHP. * * @return string */ protected function compileEndpush() { return 'stopPush(); ?>'; } /** * Compile the prepend statements into valid PHP. * * @param string $expression * @return string */ protected function compilePrepend($expression) { return "startPrepend{$expression}; ?>"; } /** * Compile the end-prepend statements into valid PHP. * * @return string */ protected function compileEndprepend() { return 'stopPrepend(); ?>'; } } Compilers/Concerns/CompilesTranslations.php000064400000002040150145556170015146 0ustar00startTranslation(); ?>'; } elseif ($expression[1] === '[') { return "startTranslation{$expression}; ?>"; } return "getFromJson{$expression}; ?>"; } /** * Compile the end-lang statements into valid PHP. * * @return string */ protected function compileEndlang() { return 'renderTranslation(); ?>'; } /** * Compile the choice statements into valid PHP. * * @param string $expression * @return string */ protected function compileChoice($expression) { return "choice{$expression}; ?>"; } } Concerns/ManagesComponents.php000064400000005343150145556170012466 0ustar00componentStack[] = $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; } } Concerns/ManagesEvents.php000064400000011663150145556170011607 0ustar00addViewEvent($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->dispatch('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->dispatch('creating: '.$view->name(), [$view]); } } Concerns/ManagesLayouts.php000064400000012003150145556170011770 0ustar00sectionStack[] = $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) { $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 $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 = []; } } Concerns/ManagesLoops.php000064400000004074150145556170011435 0ustar00loopsStack); $this->loopsStack[] = [ 'iteration' => 0, 'index' => 0, 'remaining' => $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; } } Concerns/ManagesStacks.php000064400000010315150145556170011564 0ustar00pushStack[] = $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 = []; } } Concerns/ManagesTranslations.php000064400000001403150145556170013013 0ustar00translationReplacements = $replacements; } /** * Render the current translation. * * @return string */ public function renderTranslation() { return $this->container->make('translator')->getFromJson( trim(ob_get_clean()), $this->translationReplacements ); } } Engines/CompilerEngine.php000075500000005100150145556170011555 0ustar00compiler = $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; } } Engines/Engine.php000075500000000552150145556170010070 0ustar00lastRendered; } } Engines/EngineResolver.php000075500000002374150145556170011616 0ustar00resolved[$engine]); $this->resolvers[$engine] = $resolver; } /** * Resolve an engine instance by name. * * @param string $engine * @return \Illuminate\Contracts\View\Engine * @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."); } } Engines/FileEngine.php000064400000000565150145556170010671 0ustar00evaluatePath($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; } } Factory.php000075500000032226150145556170006705 0ustar00 '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 first view that actually exists from the given list. * * @param array $views * @param array $data * @param array $mergeData * @return \Illuminate\Contracts\View\View */ public function first(array $views, $data = [], $mergeData = []) { $view = collect($views)->first(function ($view) { return $this->exists($view); }); if (! $view) { throw new InvalidArgumentException('None of the views in the given array exist.'); } return $this->make($view, $data, $mergeData); } /** * Get the rendered content of the view based on a given condition. * * @param bool $condition * @param string $view * @param array $data * @param array $mergeData * @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\Contracts\View\Engine * * @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; } } FileViewFinder.php000075500000014771150145556170010145 0ustar00files = $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; } } Middleware/ShareErrorsFromSession.php000064400000002622150145556170013774 0ustar00view = $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.php000075500000022006150145556170006203 0ustar00view = $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 string */ 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\Contracts\View\Engine */ 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')) { $class = static::class; throw new BadMethodCallException("Method {$class}::{$method} does not exist."); } return $this->with(Str::camel(substr($method, 4)), $parameters[0]); } /** * Get the string contents of the view. * * @return string */ public function __toString() { return $this->render(); } } ViewFinderInterface.php000075500000002654150145556170011163 0ustar00registerFactory(); $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']; $factory = $this->createFactory($resolver, $finder, $app['events']); // We will also set the container instance on this view environment since the // view composers may be classes registered in the container, which allows // for great testable, flexible composers for the application developer. $factory->setContainer($app); $factory->share('app', $app); return $factory; }); } /** * Create a new Factory Instance. * * @param \Illuminate\View\Engines\EngineResolver $resolver * @param \Illuminate\View\ViewFinderInterface $finder * @param \Illuminate\Contracts\Events\Dispatcher $events * @return \Illuminate\View\Factory */ protected function createFactory($resolver, $finder, $events) { return new Factory($resolver, $finder, $events); } /** * Register the view finder implementation. * * @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']); }); } } composer.json000064400000001707150145556170007304 0ustar00{ "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": "^7.1.3", "illuminate/container": "5.6.*", "illuminate/contracts": "5.6.*", "illuminate/events": "5.6.*", "illuminate/filesystem": "5.6.*", "illuminate/support": "5.6.*", "symfony/debug": "~4.0" }, "autoload": { "psr-4": { "Illuminate\\View\\": "" } }, "extra": { "branch-alias": { "dev-master": "5.6-dev" } }, "config": { "sort-packages": true }, "minimum-stability": "dev" }