PageRenderTime 25ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/myCore/lib/laravel/illuminate/view/Illuminate/View/Compilers/BladeCompiler.php

https://gitlab.com/fabian.morales/marlon_becerra
PHP | 714 lines | 286 code | 87 blank | 341 comment | 11 complexity | 7ec7629f7f6b5cb615144c75a33b3e12 MD5 | raw file
  1. <?php namespace Illuminate\View\Compilers;
  2. use Closure;
  3. class BladeCompiler extends Compiler implements CompilerInterface {
  4. /**
  5. * All of the registered extensions.
  6. *
  7. * @var array
  8. */
  9. protected $extensions = array();
  10. /**
  11. * The file currently being compiled.
  12. *
  13. * @var string
  14. */
  15. protected $path;
  16. /**
  17. * All of the available compiler functions.
  18. *
  19. * @var array
  20. */
  21. protected $compilers = array(
  22. 'Extensions',
  23. 'Statements',
  24. 'Comments',
  25. 'Echos'
  26. );
  27. /**
  28. * Array of opening and closing tags for escaped echos.
  29. *
  30. * @var array
  31. */
  32. protected $contentTags = array('{{', '}}');
  33. /**
  34. * Array of opening and closing tags for escaped echos.
  35. *
  36. * @var array
  37. */
  38. protected $escapedTags = array('{{{', '}}}');
  39. /**
  40. * Array of footer lines to be added to template.
  41. *
  42. * @var array
  43. */
  44. protected $footer = array();
  45. /**
  46. * Counter to keep track of nested forelse statements.
  47. *
  48. * @var int
  49. */
  50. protected $forelseCounter = 0;
  51. /**
  52. * Compile the view at the given path.
  53. *
  54. * @param string $path
  55. * @return void
  56. */
  57. public function compile($path = null)
  58. {
  59. $this->footer = array();
  60. if ($path)
  61. {
  62. $this->setPath($path);
  63. }
  64. $contents = $this->compileString($this->files->get($path));
  65. if ( ! is_null($this->cachePath))
  66. {
  67. $this->files->put($this->getCompiledPath($this->getPath()), $contents);
  68. }
  69. }
  70. /**
  71. * Get the path currently being compiled.
  72. *
  73. * @return string
  74. */
  75. public function getPath()
  76. {
  77. return $this->path;
  78. }
  79. /**
  80. * Set the path currently being compiled.
  81. *
  82. * @param string $path
  83. * @return void
  84. */
  85. public function setPath($path)
  86. {
  87. $this->path = $path;
  88. }
  89. /**
  90. * Compile the given Blade template contents.
  91. *
  92. * @param string $value
  93. * @return string
  94. */
  95. public function compileString($value)
  96. {
  97. $result = '';
  98. // Here we will loop through all of the tokens returned by the Zend lexer and
  99. // parse each one into the corresponding valid PHP. We will then have this
  100. // template as the correctly rendered PHP that can be rendered natively.
  101. foreach (token_get_all($value) as $token)
  102. {
  103. $result .= is_array($token) ? $this->parseToken($token) : $token;
  104. }
  105. // If there are any footer lines that need to get added to a template we will
  106. // add them here at the end of the template. This gets used mainly for the
  107. // template inheritance via the extends keyword that should be appended.
  108. if (count($this->footer) > 0)
  109. {
  110. $result = ltrim($result, PHP_EOL)
  111. .PHP_EOL.implode(PHP_EOL, array_reverse($this->footer));
  112. }
  113. return $result;
  114. }
  115. /**
  116. * Parse the tokens from the template.
  117. *
  118. * @param array $token
  119. * @return string
  120. */
  121. protected function parseToken($token)
  122. {
  123. list($id, $content) = $token;
  124. if ($id == T_INLINE_HTML)
  125. {
  126. foreach ($this->compilers as $type)
  127. {
  128. $content = $this->{"compile{$type}"}($content);
  129. }
  130. }
  131. return $content;
  132. }
  133. /**
  134. * Execute the user defined extensions.
  135. *
  136. * @param string $value
  137. * @return string
  138. */
  139. protected function compileExtensions($value)
  140. {
  141. foreach ($this->extensions as $compiler)
  142. {
  143. $value = call_user_func($compiler, $value, $this);
  144. }
  145. return $value;
  146. }
  147. /**
  148. * Compile Blade comments into valid PHP.
  149. *
  150. * @param string $value
  151. * @return string
  152. */
  153. protected function compileComments($value)
  154. {
  155. $pattern = sprintf('/%s--((.|\s)*?)--%s/', $this->contentTags[0], $this->contentTags[1]);
  156. return preg_replace($pattern, '<?php /*$1*/ ?>', $value);
  157. }
  158. /**
  159. * Compile Blade echos into valid PHP.
  160. *
  161. * @param string $value
  162. * @return string
  163. */
  164. protected function compileEchos($value)
  165. {
  166. $difference = strlen($this->contentTags[0]) - strlen($this->escapedTags[0]);
  167. if ($difference > 0)
  168. {
  169. return $this->compileEscapedEchos($this->compileRegularEchos($value));
  170. }
  171. return $this->compileRegularEchos($this->compileEscapedEchos($value));
  172. }
  173. /**
  174. * Compile Blade Statements that start with "@"
  175. *
  176. * @param string $value
  177. * @return mixed
  178. */
  179. protected function compileStatements($value)
  180. {
  181. $callback = function($match)
  182. {
  183. if (method_exists($this, $method = 'compile'.ucfirst($match[1])))
  184. {
  185. $match[0] = $this->$method(array_get($match, 3));
  186. }
  187. return isset($match[3]) ? $match[0] : $match[0].$match[2];
  188. };
  189. return preg_replace_callback('/\B@(\w+)([ \t]*)(\( ( (?>[^()]+) | (?3) )* \))?/x', $callback, $value);
  190. }
  191. /**
  192. * Compile the "regular" echo statements.
  193. *
  194. * @param string $value
  195. * @return string
  196. */
  197. protected function compileRegularEchos($value)
  198. {
  199. $pattern = sprintf('/(@)?%s\s*(.+?)\s*%s(\r?\n)?/s', $this->contentTags[0], $this->contentTags[1]);
  200. $callback = function($matches)
  201. {
  202. $whitespace = empty($matches[3]) ? '' : $matches[3].$matches[3];
  203. return $matches[1] ? substr($matches[0], 1) : '<?php echo '.$this->compileEchoDefaults($matches[2]).'; ?>'.$whitespace;
  204. };
  205. return preg_replace_callback($pattern, $callback, $value);
  206. }
  207. /**
  208. * Compile the escaped echo statements.
  209. *
  210. * @param string $value
  211. * @return string
  212. */
  213. protected function compileEscapedEchos($value)
  214. {
  215. $pattern = sprintf('/%s\s*(.+?)\s*%s(\r?\n)?/s', $this->escapedTags[0], $this->escapedTags[1]);
  216. $callback = function($matches)
  217. {
  218. $whitespace = empty($matches[2]) ? '' : $matches[2].$matches[2];
  219. return '<?php echo e('.$this->compileEchoDefaults($matches[1]).'); ?>'.$whitespace;
  220. };
  221. return preg_replace_callback($pattern, $callback, $value);
  222. }
  223. /**
  224. * Compile the default values for the echo statement.
  225. *
  226. * @param string $value
  227. * @return string
  228. */
  229. public function compileEchoDefaults($value)
  230. {
  231. return preg_replace('/^(?=\$)(.+?)(?:\s+or\s+)(.+?)$/s', 'isset($1) ? $1 : $2', $value);
  232. }
  233. /**
  234. * Compile the each statements into valid PHP.
  235. *
  236. * @param string $expression
  237. * @return string
  238. */
  239. protected function compileEach($expression)
  240. {
  241. return "<?php echo \$__env->renderEach{$expression}; ?>";
  242. }
  243. /**
  244. * Compile the yield statements into valid PHP.
  245. *
  246. * @param string $expression
  247. * @return string
  248. */
  249. protected function compileYield($expression)
  250. {
  251. return "<?php echo \$__env->yieldContent{$expression}; ?>";
  252. }
  253. /**
  254. * Compile the show statements into valid PHP.
  255. *
  256. * @param string $expression
  257. * @return string
  258. */
  259. protected function compileShow($expression)
  260. {
  261. return "<?php echo \$__env->yieldSection(); ?>";
  262. }
  263. /**
  264. * Compile the section statements into valid PHP.
  265. *
  266. * @param string $expression
  267. * @return string
  268. */
  269. protected function compileSection($expression)
  270. {
  271. return "<?php \$__env->startSection{$expression}; ?>";
  272. }
  273. /**
  274. * Compile the append statements into valid PHP.
  275. *
  276. * @param string $expression
  277. * @return string
  278. */
  279. protected function compileAppend($expression)
  280. {
  281. return "<?php \$__env->appendSection(); ?>";
  282. }
  283. /**
  284. * Compile the end-section statements into valid PHP.
  285. *
  286. * @param string $expression
  287. * @return string
  288. */
  289. protected function compileEndsection($expression)
  290. {
  291. return "<?php \$__env->stopSection(); ?>";
  292. }
  293. /**
  294. * Compile the stop statements into valid PHP.
  295. *
  296. * @param string $expression
  297. * @return string
  298. */
  299. protected function compileStop($expression)
  300. {
  301. return "<?php \$__env->stopSection(); ?>";
  302. }
  303. /**
  304. * Compile the overwrite statements into valid PHP.
  305. *
  306. * @param string $expression
  307. * @return string
  308. */
  309. protected function compileOverwrite($expression)
  310. {
  311. return "<?php \$__env->stopSection(true); ?>";
  312. }
  313. /**
  314. * Compile the unless statements into valid PHP.
  315. *
  316. * @param string $expression
  317. * @return string
  318. */
  319. protected function compileUnless($expression)
  320. {
  321. return "<?php if ( ! $expression): ?>";
  322. }
  323. /**
  324. * Compile the end unless statements into valid PHP.
  325. *
  326. * @param string $expression
  327. * @return string
  328. */
  329. protected function compileEndunless($expression)
  330. {
  331. return "<?php endif; ?>";
  332. }
  333. /**
  334. * Compile the lang statements into valid PHP.
  335. *
  336. * @param string $expression
  337. * @return string
  338. */
  339. protected function compileLang($expression)
  340. {
  341. return "<?php echo \\Illuminate\\Support\\Facades\\Lang::get$expression; ?>";
  342. }
  343. /**
  344. * Compile the choice statements into valid PHP.
  345. *
  346. * @param string $expression
  347. * @return string
  348. */
  349. protected function compileChoice($expression)
  350. {
  351. return "<?php echo \\Illuminate\\Support\\Facades\\Lang::choice$expression; ?>";
  352. }
  353. /**
  354. * Compile the else statements into valid PHP.
  355. *
  356. * @param string $expression
  357. * @return string
  358. */
  359. protected function compileElse($expression)
  360. {
  361. return "<?php else: ?>";
  362. }
  363. /**
  364. * Compile the for statements into valid PHP.
  365. *
  366. * @param string $expression
  367. * @return string
  368. */
  369. protected function compileFor($expression)
  370. {
  371. return "<?php for{$expression}: ?>";
  372. }
  373. /**
  374. * Compile the foreach statements into valid PHP.
  375. *
  376. * @param string $expression
  377. * @return string
  378. */
  379. protected function compileForeach($expression)
  380. {
  381. return "<?php foreach{$expression}: ?>";
  382. }
  383. /**
  384. * Compile the forelse statements into valid PHP.
  385. *
  386. * @param string $expression
  387. * @return string
  388. */
  389. protected function compileForelse($expression)
  390. {
  391. $empty = '$__empty_' . ++$this->forelseCounter;
  392. return "<?php {$empty} = true; foreach{$expression}: {$empty} = false; ?>";
  393. }
  394. /**
  395. * Compile the if statements into valid PHP.
  396. *
  397. * @param string $expression
  398. * @return string
  399. */
  400. protected function compileIf($expression)
  401. {
  402. return "<?php if{$expression}: ?>";
  403. }
  404. /**
  405. * Compile the else-if statements into valid PHP.
  406. *
  407. * @param string $expression
  408. * @return string
  409. */
  410. protected function compileElseif($expression)
  411. {
  412. return "<?php elseif{$expression}: ?>";
  413. }
  414. /**
  415. * Compile the forelse statements into valid PHP.
  416. *
  417. * @param string $expression
  418. * @return string
  419. */
  420. protected function compileEmpty($expression)
  421. {
  422. $empty = '$__empty_' . $this->forelseCounter--;
  423. return "<?php endforeach; if ({$empty}): ?>";
  424. }
  425. /**
  426. * Compile the while statements into valid PHP.
  427. *
  428. * @param string $expression
  429. * @return string
  430. */
  431. protected function compileWhile($expression)
  432. {
  433. return "<?php while{$expression}: ?>";
  434. }
  435. /**
  436. * Compile the end-while statements into valid PHP.
  437. *
  438. * @param string $expression
  439. * @return string
  440. */
  441. protected function compileEndwhile($expression)
  442. {
  443. return "<?php endwhile; ?>";
  444. }
  445. /**
  446. * Compile the end-for statements into valid PHP.
  447. *
  448. * @param string $expression
  449. * @return string
  450. */
  451. protected function compileEndfor($expression)
  452. {
  453. return "<?php endfor; ?>";
  454. }
  455. /**
  456. * Compile the end-for-each statements into valid PHP.
  457. *
  458. * @param string $expression
  459. * @return string
  460. */
  461. protected function compileEndforeach($expression)
  462. {
  463. return "<?php endforeach; ?>";
  464. }
  465. /**
  466. * Compile the end-if statements into valid PHP.
  467. *
  468. * @param string $expression
  469. * @return string
  470. */
  471. protected function compileEndif($expression)
  472. {
  473. return "<?php endif; ?>";
  474. }
  475. /**
  476. * Compile the end-for-else statements into valid PHP.
  477. *
  478. * @param string $expression
  479. * @return string
  480. */
  481. protected function compileEndforelse($expression)
  482. {
  483. return "<?php endif; ?>";
  484. }
  485. /**
  486. * Compile the extends statements into valid PHP.
  487. *
  488. * @param string $expression
  489. * @return string
  490. */
  491. protected function compileExtends($expression)
  492. {
  493. if (starts_with($expression, '('))
  494. {
  495. $expression = substr($expression, 1, -1);
  496. }
  497. $data = "<?php echo \$__env->make($expression, array_except(get_defined_vars(), array('__data', '__path')))->render(); ?>";
  498. $this->footer[] = $data;
  499. return '';
  500. }
  501. /**
  502. * Compile the include statements into valid PHP.
  503. *
  504. * @param string $expression
  505. * @return string
  506. */
  507. protected function compileInclude($expression)
  508. {
  509. if (starts_with($expression, '('))
  510. {
  511. $expression = substr($expression, 1, -1);
  512. }
  513. return "<?php echo \$__env->make($expression, array_except(get_defined_vars(), array('__data', '__path')))->render(); ?>";
  514. }
  515. /**
  516. * Compile the stack statements into the content
  517. *
  518. * @param string $expression
  519. * @return string
  520. */
  521. protected function compileStack($expression)
  522. {
  523. return "<?php echo \$__env->yieldContent{$expression}; ?>";
  524. }
  525. /**
  526. * Compile the push statements into valid PHP.
  527. *
  528. * @param $expression
  529. * @return string
  530. */
  531. protected function compilePush($expression)
  532. {
  533. return "<?php \$__env->startSection{$expression}; ?>";
  534. }
  535. /**
  536. * Compile the endpush statements into valid PHP.
  537. *
  538. * @param $expression
  539. * @return string
  540. */
  541. protected function compileEndpush($expression)
  542. {
  543. return "<?php \$__env->appendSection(); ?>";
  544. }
  545. /**
  546. * Register a custom Blade compiler.
  547. *
  548. * @param \Closure $compiler
  549. * @return void
  550. */
  551. public function extend(Closure $compiler)
  552. {
  553. $this->extensions[] = $compiler;
  554. }
  555. /**
  556. * Get the regular expression for a generic Blade function.
  557. *
  558. * @param string $function
  559. * @return string
  560. */
  561. public function createMatcher($function)
  562. {
  563. return '/(?<!\w)(\s*)@'.$function.'(\s*\(.*\))/';
  564. }
  565. /**
  566. * Get the regular expression for a generic Blade function.
  567. *
  568. * @param string $function
  569. * @return string
  570. */
  571. public function createOpenMatcher($function)
  572. {
  573. return '/(?<!\w)(\s*)@'.$function.'(\s*\(.*)\)/';
  574. }
  575. /**
  576. * Create a plain Blade matcher.
  577. *
  578. * @param string $function
  579. * @return string
  580. */
  581. public function createPlainMatcher($function)
  582. {
  583. return '/(?<!\w)(\s*)@'.$function.'(\s*)/';
  584. }
  585. /**
  586. * Sets the content tags used for the compiler.
  587. *
  588. * @param string $openTag
  589. * @param string $closeTag
  590. * @param bool $escaped
  591. * @return void
  592. */
  593. public function setContentTags($openTag, $closeTag, $escaped = false)
  594. {
  595. $property = ($escaped === true) ? 'escapedTags' : 'contentTags';
  596. $this->{$property} = array(preg_quote($openTag), preg_quote($closeTag));
  597. }
  598. /**
  599. * Sets the escaped content tags used for the compiler.
  600. *
  601. * @param string $openTag
  602. * @param string $closeTag
  603. * @return void
  604. */
  605. public function setEscapedContentTags($openTag, $closeTag)
  606. {
  607. $this->setContentTags($openTag, $closeTag, true);
  608. }
  609. /**
  610. * Gets the content tags used for the compiler.
  611. *
  612. * @return string
  613. */
  614. public function getContentTags()
  615. {
  616. return $this->contentTags;
  617. }
  618. /**
  619. * Gets the escaped content tags used for the compiler.
  620. *
  621. * @return string
  622. */
  623. public function getEscapedContentTags()
  624. {
  625. return $this->escapedTags;
  626. }
  627. }