namespace Illuminate\View\Compilers;
use Illuminate\Support\Arr;
use Illuminate\Support\Str;
// namespace is so cool
class BladeCompiler extends Compiler implements CompilerInterface
{// has father class and api
/**
* All of the registered extensions.
*
* @var array
*/
protected $extensions = [];// all of the registered extension.
/**
* All custom "directive" handlers.
*
* This was implemented as a more usable "extend" in 5.1.
*
* @var array
*/
protected $customDirectives = [];// All custom "directive" handlers
/**
* The file currently being compiled.
*
* @var string
*/
protected $path;// The file currently being compiled.
/**
* All of the available compiler functions.
*
* @var array
*/
protected $compilers = [
'Extensions',
'Statements',
'Comments',
'Echos',
];// All of the available compiler functions
// a function collection
/**
* Array of opening and closing tags for raw echos.
*
* @var array
*/
protected $rawTags = ['{!!', '!!}'];// Array of opening and closing tags for raw echos.
/**
* Array of opening and closing tags for regular echos.
*
* @var array
*/
protected $contentTags = ['{{', '}}'];//Array of opening and closing tags for regular echos.
/**
* Array of opening and closing tags for escaped echos.
*
* @var array
*/
protected $escapedTags = ['{{{', '}}}'];//Array of opening and closing tags for escaped echos.
/**
* The "regular" / legacy echo string format.
*
* @var string
*/
protected $echoFormat = 'e(%s)';// The "regular" /legacy echo string format.
/**
* Array of footer lines to be added to template.
*
* @var array
*/
protected $footer = [];// Array of footer lines to the added to template.
/**
* Counter to keep track of nested for else statements.
*
* @var int
*/
protected $forelseCounter = 0;//Counter to keep track of nested for else statements.
/**
* Compile the view at the given path.
*
* @param string $path
* @return void
*/
public function compile($path = null)
{//Compile the view at the given path.
if ($path) {// $path
$this->setPath($path);// path
}
$contents = $this->compileString($this->files->get($this->getPath()));// contents
// get the contents
if (! is_null($this->cachePath)) {
$this->files->put($this->getCompiledPath($this->getPath()), $contents);
}// if not null
}// return it,
/**
* Get the path currently being compiled.
*
* @return string
*/
public function getPath()
{
return $this->path;
}// big get just get you want
/**
* Set the path currently being compiled.
*
* @param string $path
* @return void
*/
public function setPath($path)
{
$this->path = $path;
}// set Path
/**
* Compile the given Blade template contents.
*
* @param string $value
* @return string
*/
public function compileString($value)
{//Compile the given Blade template contents.
$result = '';// this result
$this->footer = [];// 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;
}// token_get_all
//loop the token_get_all
// 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 = ltrim($result, PHP_EOL)
.PHP_EOL.implode(PHP_EOL, array_reverse($this->footer));
}// append something
return $result;//return result
}
/**
* Parse the tokens from the template.
*
* @param array $token
* @return string
*/
protected function parseToken($token)
{//Parse the tokens from the template.
list($id, $content) = $token;//get list
if ($id == T_INLINE_HTML) {// a special id
foreach ($this->compilers as $type) {// loop compile
$content = $this->{"compile{$type}"}($content);// this is a good use
//$content = $this=>{"compile{$type}"}($content);
}
}
return $content;//return this type
}// a classic function type
/**
* 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);
}// loop extensions and call_user_func
return $value;
}//Execute the user defined extensions
/**
* Compile Blade comments into valid PHP.
*
* @param string $value
* @return string
*/
protected function compileComments($value)
{
$pattern = sprintf('/%s--((.|\s)*?)--%s/', $this->contentTags[0], $this->contentTags[1]);
// get the pattern
// a very good function type
// just comments
return preg_replace($pattern, '<?php /*$1*/ ?>', $value);
}//compile Blade comments into valid PHP
/**
* Compile Blade echos into valid PHP.
*
* @param string $value
* @return string
*/
protected function compileEchos($value)
{//compile Blade echos into valid PHP.
foreach ($this->getEchoMethods() as $method => $length) {
$value = $this->$method($value);//get the value
}// foreach
return $value;
}// return $value
/**
* Get the echo methods in the proper order for compilation.
*
* @return array
*/
protected function getEchoMethods()
{//Get the echo methods in the proper order for compilation.
$methods = [
'compileRawEchos' => strlen(stripcslashes($this->rawTags[0])),
'compileEscapedEchos' => strlen(stripcslashes($this->escapedTags[0])),
'compileRegularEchos' => strlen(stripcslashes($this->contentTags[0])),
];// set some regular method to use
uksort($methods, function ($method1, $method2) use ($methods) {
// use user define method to sort the array
// Ensure the longest tags are processed first
if ($methods[$method1] > $methods[$method2]) {
return -1;
}
if ($methods[$method1] < $methods[$method2]) {
return 1;
}
// Otherwise give preference to raw tags (assuming they've overridden)
if ($method1 === 'compileRawEchos') {
return -1;
}
if ($method2 === 'compileRawEchos') {
return 1;
}
if ($method1 === 'compileEscapedEchos') {
return -1;
}
if ($method2 === 'compileEscapedEchos') {
return 1;
}
});
return $methods;
}// The methods.