progetto fatto precedentemente adattato al framework creato con il corso
filippo.bertilotti
2024-06-12 5dd12c2939637d0af09bb385f12f24868bfc17c7
commit | author | age
15e03a 1 <?php
F 2
3 namespace Framework;
4
5 class MVCTemplateViewer implements TemplateViewerInterface {
6     public function render(string $template, array $data = []): string {
7
8         $views_dir = dirname(__DIR__, 2) . "/views/";
9
10         $code = file_get_contents($views_dir . $template);
11
12         if(preg_match('#^{% extends "(?<template>.*)" %}#', $code, $matches) === 1) {
13             $base = file_get_contents($views_dir . $matches["template"]);
14             $blocks = $this->getBlocks($code);
15             $code = $this->replaceYields($base, $blocks);
16         }
17
18         $code = $this->loadIncludes($views_dir, $code);
19
20         $code = $this->replaceVariables($code);
21
22         $code = $this->replacePHP($code);
23
24         extract($data, EXTR_SKIP);
25
26         ob_start();
27         eval("?>$code");
28
29         return ob_get_clean();
30         
31     }
32
33     public function replaceVariables(string $code) : string {
34         return preg_replace("#{{\s*(\S+)\s*}}#", "<?= htmlspecialchars(\$$1 ?? \"\") ?>", $code);
35     }
36
37     public function replacePHP(string $code) : string {
38         return preg_replace("#{%\s*(.+)\s*%}#", "<?php $1 ?>", $code);
39     }
40
41     private function getBlocks(string $code) : array {
42         preg_match_all("#{% block (?<name>\w+) %}(?<content>.*?){% endblock %}#s" , $code, $matches, PREG_SET_ORDER);
43         
44         $blocks = [];
45         
46         foreach($matches as $match) {
47             $blocks[$match["name"]] = $match["content"];
48         }
49         
50         return $blocks;
51         
52     }
53
54     private function replaceYields(string $code, array $blocks): string {
55         preg_match_all("#{% yield (?<name>\w+) %}#", $code, $matches, PREG_SET_ORDER);
56
57         foreach($matches as $match) {
58             $name = $match["name"];
59             $block = $blocks[$name];
60
61             $code = preg_replace("#{% yield $name %}#", $block, $code);
62         }
63         return $code;
64     }
65
66     private function loadIncludes(string $dir, string $code): string {
67         preg_match_all('#{% include "(?<template>.*?)" %}#', $code, $matches, PREG_SET_ORDER);
68         foreach($matches as $match) {
69             $template = $match['template'];
70
71             $contents = file_get_contents($dir . $template);
72
73             $code = preg_replace("#{% include \"$template\" %}#", $contents, $code);
74         }
75
76         return $code;
77     }
78 }