25'ten fazla konu seçemezsiniz Konular bir harf veya rakamla başlamalı, kısa çizgiler ('-') içerebilir ve en fazla 35 karakter uzunluğunda olabilir.

107 satır
3.3KB

  1. <?php
  2. namespace Framework\View\Engine;
  3. use Framework\View\Engine\HasManager;
  4. use Framework\View\View;
  5. use function view;
  6. class AdvancedEngine implements Engine
  7. {
  8. use HasManager;
  9. protected $layouts = [];
  10. public function render(View $view): string
  11. {
  12. $hash = md5($view->path);
  13. $folder = __DIR__ . '/../../../storage/framework/views';
  14. if (!is_file("{$folder}/{$hash}.php")) {
  15. touch("{$folder}/{$hash}.php");
  16. }
  17. $cached = realpath("{$folder}/{$hash}.php");
  18. if (!file_exists($hash) || filemtime($view->path) > filemtime($hash)) {
  19. $content = $this->compile(file_get_contents($view->path));
  20. file_put_contents($cached, $content);
  21. }
  22. extract($view->data);
  23. ob_start();
  24. include($cached);
  25. $contents = ob_get_contents();
  26. ob_end_clean();
  27. if ($layout = $this->layouts[$cached] ?? null) {
  28. $contentsWithLayout = view($layout, array_merge(
  29. $view->data,
  30. ['contents' => $contents],
  31. ));
  32. return $contentsWithLayout;
  33. }
  34. return $contents;
  35. }
  36. protected function compile(string $template): string
  37. {
  38. // replace `@extends` with `$this->extends`
  39. $template = preg_replace_callback('#@extends\(((?<=\().*(?=\)))\)#', function($matches) {
  40. return '<?php $this->extends(' . $matches[1] . '); ?>';
  41. }, $template);
  42. // replace `@if` with `if(...):`
  43. $template = preg_replace_callback('#@if\(((?<=\().*(?=\)))\)#', function($matches) {
  44. return '<?php if(' . $matches[1] . '): ?>';
  45. }, $template);
  46. // replace `@endif` with `endif;`
  47. $template = preg_replace_callback('#@endif#', function($matches) {
  48. return '<?php endif; ?>';
  49. }, $template);
  50. // replace `@foreach` with `foreach(...):`
  51. $template = preg_replace_callback('#@foreach\(((?<=\().*(?=\)))\)#', function($matches) {
  52. return '<?php foreach(' . $matches[1] . '): ?>';
  53. }, $template);
  54. // replace `@endforeach` with `endforeach;`
  55. $template = preg_replace_callback('#@endforeach#', function($matches) {
  56. return '<?php endforeach; ?>';
  57. }, $template);
  58. // replace `@[anything](...)` with `$this->[anything](...)`
  59. $template = preg_replace_callback('#\s+@([^(]+)\(((?<=\().*(?=\)))\)#', function($matches) {
  60. return '<?php $this->' . $matches[1] . '(' . $matches[2] . '); ?>';
  61. }, $template);
  62. // replace `{{ ... }}` with `print $this->escape(...)`
  63. $template = preg_replace_callback('#\{\{([^}]*)\}\}#', function($matches) {
  64. return '<?php print $this->escape(' . $matches[1] . '); ?>';
  65. }, $template);
  66. // replace `{!! ... !!}` with `print ...`
  67. $template = preg_replace_callback('#\{!!([^}]+)!!\}#', function($matches) {
  68. return '<?php print ' . $matches[1] . '; ?>';
  69. }, $template);
  70. return $template;
  71. }
  72. protected function extends(string $template): static
  73. {
  74. $backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 1);
  75. $this->layouts[realpath($backtrace[0]['file'])] = $template;
  76. return $this;
  77. }
  78. public function __call(string $name, $values)
  79. {
  80. return $this->manager->useMacro($name, ...$values);
  81. }
  82. }

Powered by TurnKey Linux.