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