PageRenderTime 45ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 1ms

/vendor/laravel/framework/src/Illuminate/View/Compilers/BladeCompiler.php

https://gitlab.com/ealexis.t/trends
PHP | 1057 lines | 421 code | 130 blank | 506 comment | 21 complexity | 91c40391b98b20c0ab4f026c12e33cd0 MD5 | raw file
  1. <?php
  2. namespace Illuminate\View\Compilers;
  3. use Illuminate\Support\Arr;
  4. use Illuminate\Support\Str;
  5. class BladeCompiler extends Compiler implements CompilerInterface
  6. {
  7. /**
  8. * All of the registered extensions.
  9. *
  10. * @var array
  11. */
  12. protected $extensions = [];
  13. /**
  14. * All custom "directive" handlers.
  15. *
  16. * This was implemented as a more usable "extend" in 5.1.
  17. *
  18. * @var array
  19. */
  20. protected $customDirectives = [];
  21. /**
  22. * The file currently being compiled.
  23. *
  24. * @var string
  25. */
  26. protected $path;
  27. /**
  28. * All of the available compiler functions.
  29. *
  30. * @var array
  31. */
  32. protected $compilers = [
  33. 'Extensions',
  34. 'Statements',
  35. 'Comments',
  36. 'Echos',
  37. ];
  38. /**
  39. * Array of opening and closing tags for raw echos.
  40. *
  41. * @var array
  42. */
  43. protected $rawTags = ['{!!', '!!}'];
  44. /**
  45. * Array of opening and closing tags for regular echos.
  46. *
  47. * @var array
  48. */
  49. protected $contentTags = ['{{', '}}'];
  50. /**
  51. * Array of opening and closing tags for escaped echos.
  52. *
  53. * @var array
  54. */
  55. protected $escapedTags = ['{{{', '}}}'];
  56. /**
  57. * The "regular" / legacy echo string format.
  58. *
  59. * @var string
  60. */
  61. protected $echoFormat = 'e(%s)';
  62. /**
  63. * Array of footer lines to be added to template.
  64. *
  65. * @var array
  66. */
  67. protected $footer = [];
  68. /**
  69. * Placeholder to temporary mark the position of verbatim blocks.
  70. *
  71. * @var string
  72. */
  73. protected $verbatimPlaceholder = '@__verbatim__@';
  74. /**
  75. * Array to temporary store the verbatim blocks found in the template.
  76. *
  77. * @var array
  78. */
  79. protected $verbatimBlocks = [];
  80. /**
  81. * Counter to keep track of nested forelse statements.
  82. *
  83. * @var int
  84. */
  85. protected $forelseCounter = 0;
  86. /**
  87. * Compile the view at the given path.
  88. *
  89. * @param string $path
  90. * @return void
  91. */
  92. public function compile($path = null)
  93. {
  94. if ($path) {
  95. $this->setPath($path);
  96. }
  97. if (! is_null($this->cachePath)) {
  98. $contents = $this->compileString($this->files->get($this->getPath()));
  99. $this->files->put($this->getCompiledPath($this->getPath()), $contents);
  100. }
  101. }
  102. /**
  103. * Get the path currently being compiled.
  104. *
  105. * @return string
  106. */
  107. public function getPath()
  108. {
  109. return $this->path;
  110. }
  111. /**
  112. * Set the path currently being compiled.
  113. *
  114. * @param string $path
  115. * @return void
  116. */
  117. public function setPath($path)
  118. {
  119. $this->path = $path;
  120. }
  121. /**
  122. * Compile the given Blade template contents.
  123. *
  124. * @param string $value
  125. * @return string
  126. */
  127. public function compileString($value)
  128. {
  129. $result = '';
  130. if (strpos($value, '@verbatim') !== false) {
  131. $value = $this->storeVerbatimBlocks($value);
  132. }
  133. $this->footer = [];
  134. // Here we will loop through all of the tokens returned by the Zend lexer and
  135. // parse each one into the corresponding valid PHP. We will then have this
  136. // template as the correctly rendered PHP that can be rendered natively.
  137. foreach (token_get_all($value) as $token) {
  138. $result .= is_array($token) ? $this->parseToken($token) : $token;
  139. }
  140. if (! empty($this->verbatimBlocks)) {
  141. $result = $this->restoreVerbatimBlocks($result);
  142. }
  143. // If there are any footer lines that need to get added to a template we will
  144. // add them here at the end of the template. This gets used mainly for the
  145. // template inheritance via the extends keyword that should be appended.
  146. if (count($this->footer) > 0) {
  147. $result = ltrim($result, PHP_EOL)
  148. .PHP_EOL.implode(PHP_EOL, array_reverse($this->footer));
  149. }
  150. return $result;
  151. }
  152. /**
  153. * Store the verbatim blocks and replace them with a temporary placeholder.
  154. *
  155. * @param string $value
  156. * @return string
  157. */
  158. protected function storeVerbatimBlocks($value)
  159. {
  160. return preg_replace_callback('/(?<!@)@verbatim(.*?)@endverbatim/s', function ($matches) {
  161. $this->verbatimBlocks[] = $matches[1];
  162. return $this->verbatimPlaceholder;
  163. }, $value);
  164. }
  165. /**
  166. * Replace the raw placeholders with the original code stored in the raw blocks.
  167. *
  168. * @param string $result
  169. * @return string
  170. */
  171. protected function restoreVerbatimBlocks($result)
  172. {
  173. $result = preg_replace_callback('/'.preg_quote($this->verbatimPlaceholder).'/', function () {
  174. return array_shift($this->verbatimBlocks);
  175. }, $result);
  176. $this->verbatimBlocks = [];
  177. return $result;
  178. }
  179. /**
  180. * Parse the tokens from the template.
  181. *
  182. * @param array $token
  183. * @return string
  184. */
  185. protected function parseToken($token)
  186. {
  187. list($id, $content) = $token;
  188. if ($id == T_INLINE_HTML) {
  189. foreach ($this->compilers as $type) {
  190. $content = $this->{"compile{$type}"}($content);
  191. }
  192. }
  193. return $content;
  194. }
  195. /**
  196. * Execute the user defined extensions.
  197. *
  198. * @param string $value
  199. * @return string
  200. */
  201. protected function compileExtensions($value)
  202. {
  203. foreach ($this->extensions as $compiler) {
  204. $value = call_user_func($compiler, $value, $this);
  205. }
  206. return $value;
  207. }
  208. /**
  209. * Compile Blade comments into valid PHP.
  210. *
  211. * @param string $value
  212. * @return string
  213. */
  214. protected function compileComments($value)
  215. {
  216. $pattern = sprintf('/%s--(.*?)--%s/s', $this->contentTags[0], $this->contentTags[1]);
  217. return preg_replace($pattern, '<?php /*$1*/ ?>', $value);
  218. }
  219. /**
  220. * Compile Blade echos into valid PHP.
  221. *
  222. * @param string $value
  223. * @return string
  224. */
  225. protected function compileEchos($value)
  226. {
  227. foreach ($this->getEchoMethods() as $method => $length) {
  228. $value = $this->$method($value);
  229. }
  230. return $value;
  231. }
  232. /**
  233. * Get the echo methods in the proper order for compilation.
  234. *
  235. * @return array
  236. */
  237. protected function getEchoMethods()
  238. {
  239. $methods = [
  240. 'compileRawEchos' => strlen(stripcslashes($this->rawTags[0])),
  241. 'compileEscapedEchos' => strlen(stripcslashes($this->escapedTags[0])),
  242. 'compileRegularEchos' => strlen(stripcslashes($this->contentTags[0])),
  243. ];
  244. uksort($methods, function ($method1, $method2) use ($methods) {
  245. // Ensure the longest tags are processed first
  246. if ($methods[$method1] > $methods[$method2]) {
  247. return -1;
  248. }
  249. if ($methods[$method1] < $methods[$method2]) {
  250. return 1;
  251. }
  252. // Otherwise give preference to raw tags (assuming they've overridden)
  253. if ($method1 === 'compileRawEchos') {
  254. return -1;
  255. }
  256. if ($method2 === 'compileRawEchos') {
  257. return 1;
  258. }
  259. if ($method1 === 'compileEscapedEchos') {
  260. return -1;
  261. }
  262. if ($method2 === 'compileEscapedEchos') {
  263. return 1;
  264. }
  265. });
  266. return $methods;
  267. }
  268. /**
  269. * Compile Blade statements that start with "@".
  270. *
  271. * @param string $value
  272. * @return mixed
  273. */
  274. protected function compileStatements($value)
  275. {
  276. $callback = function ($match) {
  277. if (Str::contains($match[1], '@')) {
  278. $match[0] = isset($match[3]) ? $match[1].$match[3] : $match[1];
  279. } elseif (isset($this->customDirectives[$match[1]])) {
  280. $match[0] = call_user_func($this->customDirectives[$match[1]], Arr::get($match, 3));
  281. } elseif (method_exists($this, $method = 'compile'.ucfirst($match[1]))) {
  282. $match[0] = $this->$method(Arr::get($match, 3));
  283. }
  284. return isset($match[3]) ? $match[0] : $match[0].$match[2];
  285. };
  286. return preg_replace_callback('/\B@(@?\w+)([ \t]*)(\( ( (?>[^()]+) | (?3) )* \))?/x', $callback, $value);
  287. }
  288. /**
  289. * Compile the "raw" echo statements.
  290. *
  291. * @param string $value
  292. * @return string
  293. */
  294. protected function compileRawEchos($value)
  295. {
  296. $pattern = sprintf('/(@)?%s\s*(.+?)\s*%s(\r?\n)?/s', $this->rawTags[0], $this->rawTags[1]);
  297. $callback = function ($matches) {
  298. $whitespace = empty($matches[3]) ? '' : $matches[3].$matches[3];
  299. return $matches[1] ? substr($matches[0], 1) : '<?php echo '.$this->compileEchoDefaults($matches[2]).'; ?>'.$whitespace;
  300. };
  301. return preg_replace_callback($pattern, $callback, $value);
  302. }
  303. /**
  304. * Compile the "regular" echo statements.
  305. *
  306. * @param string $value
  307. * @return string
  308. */
  309. protected function compileRegularEchos($value)
  310. {
  311. $pattern = sprintf('/(@)?%s\s*(.+?)\s*%s(\r?\n)?/s', $this->contentTags[0], $this->contentTags[1]);
  312. $callback = function ($matches) {
  313. $whitespace = empty($matches[3]) ? '' : $matches[3].$matches[3];
  314. $wrapped = sprintf($this->echoFormat, $this->compileEchoDefaults($matches[2]));
  315. return $matches[1] ? substr($matches[0], 1) : '<?php echo '.$wrapped.'; ?>'.$whitespace;
  316. };
  317. return preg_replace_callback($pattern, $callback, $value);
  318. }
  319. /**
  320. * Compile the escaped echo statements.
  321. *
  322. * @param string $value
  323. * @return string
  324. */
  325. protected function compileEscapedEchos($value)
  326. {
  327. $pattern = sprintf('/(@)?%s\s*(.+?)\s*%s(\r?\n)?/s', $this->escapedTags[0], $this->escapedTags[1]);
  328. $callback = function ($matches) {
  329. $whitespace = empty($matches[3]) ? '' : $matches[3].$matches[3];
  330. return $matches[1] ? $matches[0] : '<?php echo e('.$this->compileEchoDefaults($matches[2]).'); ?>'.$whitespace;
  331. };
  332. return preg_replace_callback($pattern, $callback, $value);
  333. }
  334. /**
  335. * Compile the default values for the echo statement.
  336. *
  337. * @param string $value
  338. * @return string
  339. */
  340. public function compileEchoDefaults($value)
  341. {
  342. return preg_replace('/^(?=\$)(.+?)(?:\s+or\s+)(.+?)$/s', 'isset($1) ? $1 : $2', $value);
  343. }
  344. /**
  345. * Compile the each statements into valid PHP.
  346. *
  347. * @param string $expression
  348. * @return string
  349. */
  350. protected function compileEach($expression)
  351. {
  352. return "<?php echo \$__env->renderEach{$expression}; ?>";
  353. }
  354. /**
  355. * Compile the inject statements into valid PHP.
  356. *
  357. * @param string $expression
  358. * @return string
  359. */
  360. protected function compileInject($expression)
  361. {
  362. $segments = explode(',', preg_replace("/[\(\)\\\"\']/", '', $expression));
  363. return '<?php $'.trim($segments[0])." = app('".trim($segments[1])."'); ?>";
  364. }
  365. /**
  366. * Compile the yield statements into valid PHP.
  367. *
  368. * @param string $expression
  369. * @return string
  370. */
  371. protected function compileYield($expression)
  372. {
  373. return "<?php echo \$__env->yieldContent{$expression}; ?>";
  374. }
  375. /**
  376. * Compile the show statements into valid PHP.
  377. *
  378. * @param string $expression
  379. * @return string
  380. */
  381. protected function compileShow($expression)
  382. {
  383. return '<?php echo $__env->yieldSection(); ?>';
  384. }
  385. /**
  386. * Compile the section statements into valid PHP.
  387. *
  388. * @param string $expression
  389. * @return string
  390. */
  391. protected function compileSection($expression)
  392. {
  393. return "<?php \$__env->startSection{$expression}; ?>";
  394. }
  395. /**
  396. * Compile the append statements into valid PHP.
  397. *
  398. * @param string $expression
  399. * @return string
  400. */
  401. protected function compileAppend($expression)
  402. {
  403. return '<?php $__env->appendSection(); ?>';
  404. }
  405. /**
  406. * Compile the end-section statements into valid PHP.
  407. *
  408. * @param string $expression
  409. * @return string
  410. */
  411. protected function compileEndsection($expression)
  412. {
  413. return '<?php $__env->stopSection(); ?>';
  414. }
  415. /**
  416. * Compile the stop statements into valid PHP.
  417. *
  418. * @param string $expression
  419. * @return string
  420. */
  421. protected function compileStop($expression)
  422. {
  423. return '<?php $__env->stopSection(); ?>';
  424. }
  425. /**
  426. * Compile the overwrite statements into valid PHP.
  427. *
  428. * @param string $expression
  429. * @return string
  430. */
  431. protected function compileOverwrite($expression)
  432. {
  433. return '<?php $__env->stopSection(true); ?>';
  434. }
  435. /**
  436. * Compile the unless statements into valid PHP.
  437. *
  438. * @param string $expression
  439. * @return string
  440. */
  441. protected function compileUnless($expression)
  442. {
  443. return "<?php if ( ! $expression): ?>";
  444. }
  445. /**
  446. * Compile the end unless statements into valid PHP.
  447. *
  448. * @param string $expression
  449. * @return string
  450. */
  451. protected function compileEndunless($expression)
  452. {
  453. return '<?php endif; ?>';
  454. }
  455. /**
  456. * Compile the lang statements into valid PHP.
  457. *
  458. * @param string $expression
  459. * @return string
  460. */
  461. protected function compileLang($expression)
  462. {
  463. return "<?php echo app('translator')->get$expression; ?>";
  464. }
  465. /**
  466. * Compile the choice statements into valid PHP.
  467. *
  468. * @param string $expression
  469. * @return string
  470. */
  471. protected function compileChoice($expression)
  472. {
  473. return "<?php echo app('translator')->choice$expression; ?>";
  474. }
  475. /**
  476. * Compile the else statements into valid PHP.
  477. *
  478. * @param string $expression
  479. * @return string
  480. */
  481. protected function compileElse($expression)
  482. {
  483. return '<?php else: ?>';
  484. }
  485. /**
  486. * Compile the for statements into valid PHP.
  487. *
  488. * @param string $expression
  489. * @return string
  490. */
  491. protected function compileFor($expression)
  492. {
  493. return "<?php for{$expression}: ?>";
  494. }
  495. /**
  496. * Compile the foreach statements into valid PHP.
  497. *
  498. * @param string $expression
  499. * @return string
  500. */
  501. protected function compileForeach($expression)
  502. {
  503. return "<?php foreach{$expression}: ?>";
  504. }
  505. /**
  506. * Compile the break statements into valid PHP.
  507. *
  508. * @param string $expression
  509. * @return string
  510. */
  511. protected function compileBreak($expression)
  512. {
  513. return $expression ? "<?php if{$expression} break; ?>" : '<?php break; ?>';
  514. }
  515. /**
  516. * Compile the continue statements into valid PHP.
  517. *
  518. * @param string $expression
  519. * @return string
  520. */
  521. protected function compileContinue($expression)
  522. {
  523. return $expression ? "<?php if{$expression} continue; ?>" : '<?php continue; ?>';
  524. }
  525. /**
  526. * Compile the forelse statements into valid PHP.
  527. *
  528. * @param string $expression
  529. * @return string
  530. */
  531. protected function compileForelse($expression)
  532. {
  533. $empty = '$__empty_'.++$this->forelseCounter;
  534. return "<?php {$empty} = true; foreach{$expression}: {$empty} = false; ?>";
  535. }
  536. /**
  537. * Compile the can statements into valid PHP.
  538. *
  539. * @param string $expression
  540. * @return string
  541. */
  542. protected function compileCan($expression)
  543. {
  544. return "<?php if (app('Illuminate\\Contracts\\Auth\\Access\\Gate')->check{$expression}): ?>";
  545. }
  546. /**
  547. * Compile the else-can statements into valid PHP.
  548. *
  549. * @param string $expression
  550. * @return string
  551. */
  552. protected function compileElsecan($expression)
  553. {
  554. return "<?php elseif (app('Illuminate\\Contracts\\Auth\\Access\\Gate')->check{$expression}): ?>";
  555. }
  556. /**
  557. * Compile the cannot statements into valid PHP.
  558. *
  559. * @param string $expression
  560. * @return string
  561. */
  562. protected function compileCannot($expression)
  563. {
  564. return "<?php if (app('Illuminate\\Contracts\\Auth\\Access\\Gate')->denies{$expression}): ?>";
  565. }
  566. /**
  567. * Compile the else-can statements into valid PHP.
  568. *
  569. * @param string $expression
  570. * @return string
  571. */
  572. protected function compileElsecannot($expression)
  573. {
  574. return "<?php elseif (app('Illuminate\\Contracts\\Auth\\Access\\Gate')->denies{$expression}): ?>";
  575. }
  576. /**
  577. * Compile the if statements into valid PHP.
  578. *
  579. * @param string $expression
  580. * @return string
  581. */
  582. protected function compileIf($expression)
  583. {
  584. return "<?php if{$expression}: ?>";
  585. }
  586. /**
  587. * Compile the else-if statements into valid PHP.
  588. *
  589. * @param string $expression
  590. * @return string
  591. */
  592. protected function compileElseif($expression)
  593. {
  594. return "<?php elseif{$expression}: ?>";
  595. }
  596. /**
  597. * Compile the forelse statements into valid PHP.
  598. *
  599. * @param string $expression
  600. * @return string
  601. */
  602. protected function compileEmpty($expression)
  603. {
  604. $empty = '$__empty_'.$this->forelseCounter--;
  605. return "<?php endforeach; if ({$empty}): ?>";
  606. }
  607. /**
  608. * Compile the has section statements into valid PHP.
  609. *
  610. * @param string $expression
  611. * @return string
  612. */
  613. protected function compileHasSection($expression)
  614. {
  615. return "<?php if (! empty(trim(\$__env->yieldContent{$expression}))): ?>";
  616. }
  617. /**
  618. * Compile the while statements into valid PHP.
  619. *
  620. * @param string $expression
  621. * @return string
  622. */
  623. protected function compileWhile($expression)
  624. {
  625. return "<?php while{$expression}: ?>";
  626. }
  627. /**
  628. * Compile the end-while statements into valid PHP.
  629. *
  630. * @param string $expression
  631. * @return string
  632. */
  633. protected function compileEndwhile($expression)
  634. {
  635. return '<?php endwhile; ?>';
  636. }
  637. /**
  638. * Compile the end-for statements into valid PHP.
  639. *
  640. * @param string $expression
  641. * @return string
  642. */
  643. protected function compileEndfor($expression)
  644. {
  645. return '<?php endfor; ?>';
  646. }
  647. /**
  648. * Compile the end-for-each statements into valid PHP.
  649. *
  650. * @param string $expression
  651. * @return string
  652. */
  653. protected function compileEndforeach($expression)
  654. {
  655. return '<?php endforeach; ?>';
  656. }
  657. /**
  658. * Compile the end-can statements into valid PHP.
  659. *
  660. * @param string $expression
  661. * @return string
  662. */
  663. protected function compileEndcan($expression)
  664. {
  665. return '<?php endif; ?>';
  666. }
  667. /**
  668. * Compile the end-cannot statements into valid PHP.
  669. *
  670. * @param string $expression
  671. * @return string
  672. */
  673. protected function compileEndcannot($expression)
  674. {
  675. return '<?php endif; ?>';
  676. }
  677. /**
  678. * Compile the end-if statements into valid PHP.
  679. *
  680. * @param string $expression
  681. * @return string
  682. */
  683. protected function compileEndif($expression)
  684. {
  685. return '<?php endif; ?>';
  686. }
  687. /**
  688. * Compile the end-for-else statements into valid PHP.
  689. *
  690. * @param string $expression
  691. * @return string
  692. */
  693. protected function compileEndforelse($expression)
  694. {
  695. return '<?php endif; ?>';
  696. }
  697. /**
  698. * Compile the raw PHP statements into valid PHP.
  699. *
  700. * @param string $expression
  701. * @return string
  702. */
  703. protected function compilePhp($expression)
  704. {
  705. return $expression ? "<?php {$expression}; ?>" : '<?php ';
  706. }
  707. /**
  708. * Compile end-php statement into valid PHP.
  709. *
  710. * @param string $expression
  711. * @return string
  712. */
  713. protected function compileEndphp($expression)
  714. {
  715. return ' ?>';
  716. }
  717. /**
  718. * Compile the unset statements into valid PHP.
  719. *
  720. * @param string $expression
  721. * @return string
  722. */
  723. protected function compileUnset($expression)
  724. {
  725. return "<?php unset{$expression}; ?>";
  726. }
  727. /**
  728. * Compile the extends statements into valid PHP.
  729. *
  730. * @param string $expression
  731. * @return string
  732. */
  733. protected function compileExtends($expression)
  734. {
  735. $expression = $this->stripParentheses($expression);
  736. $data = "<?php echo \$__env->make($expression, array_except(get_defined_vars(), array('__data', '__path')))->render(); ?>";
  737. $this->footer[] = $data;
  738. return '';
  739. }
  740. /**
  741. * Compile the include statements into valid PHP.
  742. *
  743. * @param string $expression
  744. * @return string
  745. */
  746. protected function compileInclude($expression)
  747. {
  748. $expression = $this->stripParentheses($expression);
  749. return "<?php echo \$__env->make($expression, array_except(get_defined_vars(), array('__data', '__path')))->render(); ?>";
  750. }
  751. /**
  752. * Compile the include statements into valid PHP.
  753. *
  754. * @param string $expression
  755. * @return string
  756. */
  757. protected function compileIncludeIf($expression)
  758. {
  759. $expression = $this->stripParentheses($expression);
  760. return "<?php if (\$__env->exists($expression)) echo \$__env->make($expression, array_except(get_defined_vars(), array('__data', '__path')))->render(); ?>";
  761. }
  762. /**
  763. * Compile the stack statements into the content.
  764. *
  765. * @param string $expression
  766. * @return string
  767. */
  768. protected function compileStack($expression)
  769. {
  770. return "<?php echo \$__env->yieldPushContent{$expression}; ?>";
  771. }
  772. /**
  773. * Compile the push statements into valid PHP.
  774. *
  775. * @param string $expression
  776. * @return string
  777. */
  778. protected function compilePush($expression)
  779. {
  780. return "<?php \$__env->startPush{$expression}; ?>";
  781. }
  782. /**
  783. * Compile the endpush statements into valid PHP.
  784. *
  785. * @param string $expression
  786. * @return string
  787. */
  788. protected function compileEndpush($expression)
  789. {
  790. return '<?php $__env->stopPush(); ?>';
  791. }
  792. /**
  793. * Strip the parentheses from the given expression.
  794. *
  795. * @param string $expression
  796. * @return string
  797. */
  798. protected function stripParentheses($expression)
  799. {
  800. if (Str::startsWith($expression, '(')) {
  801. $expression = substr($expression, 1, -1);
  802. }
  803. return $expression;
  804. }
  805. /**
  806. * Get the extensions used by the compiler.
  807. *
  808. * @return array
  809. */
  810. public function getExtensions()
  811. {
  812. return $this->extensions;
  813. }
  814. /**
  815. * Register a custom Blade compiler.
  816. *
  817. * @param callable $compiler
  818. * @return void
  819. */
  820. public function extend(callable $compiler)
  821. {
  822. $this->extensions[] = $compiler;
  823. }
  824. /**
  825. * Register a handler for custom directives.
  826. *
  827. * @param string $name
  828. * @param callable $handler
  829. * @return void
  830. */
  831. public function directive($name, callable $handler)
  832. {
  833. $this->customDirectives[$name] = $handler;
  834. }
  835. /**
  836. * Get the list of custom directives.
  837. *
  838. * @return array
  839. */
  840. public function getCustomDirectives()
  841. {
  842. return $this->customDirectives;
  843. }
  844. /**
  845. * Gets the raw tags used by the compiler.
  846. *
  847. * @return array
  848. */
  849. public function getRawTags()
  850. {
  851. return $this->rawTags;
  852. }
  853. /**
  854. * Sets the raw tags used for the compiler.
  855. *
  856. * @param string $openTag
  857. * @param string $closeTag
  858. * @return void
  859. */
  860. public function setRawTags($openTag, $closeTag)
  861. {
  862. $this->rawTags = [preg_quote($openTag), preg_quote($closeTag)];
  863. }
  864. /**
  865. * Sets the content tags used for the compiler.
  866. *
  867. * @param string $openTag
  868. * @param string $closeTag
  869. * @param bool $escaped
  870. * @return void
  871. */
  872. public function setContentTags($openTag, $closeTag, $escaped = false)
  873. {
  874. $property = ($escaped === true) ? 'escapedTags' : 'contentTags';
  875. $this->{$property} = [preg_quote($openTag), preg_quote($closeTag)];
  876. }
  877. /**
  878. * Sets the escaped content tags used for the compiler.
  879. *
  880. * @param string $openTag
  881. * @param string $closeTag
  882. * @return void
  883. */
  884. public function setEscapedContentTags($openTag, $closeTag)
  885. {
  886. $this->setContentTags($openTag, $closeTag, true);
  887. }
  888. /**
  889. * Gets the content tags used for the compiler.
  890. *
  891. * @return string
  892. */
  893. public function getContentTags()
  894. {
  895. return $this->getTags();
  896. }
  897. /**
  898. * Gets the escaped content tags used for the compiler.
  899. *
  900. * @return string
  901. */
  902. public function getEscapedContentTags()
  903. {
  904. return $this->getTags(true);
  905. }
  906. /**
  907. * Gets the tags used for the compiler.
  908. *
  909. * @param bool $escaped
  910. * @return array
  911. */
  912. protected function getTags($escaped = false)
  913. {
  914. $tags = $escaped ? $this->escapedTags : $this->contentTags;
  915. return array_map('stripcslashes', $tags);
  916. }
  917. /**
  918. * Set the echo format to be used by the compiler.
  919. *
  920. * @param string $format
  921. * @return void
  922. */
  923. public function setEchoFormat($format)
  924. {
  925. $this->echoFormat = $format;
  926. }
  927. }