1<?php
2
3
4namespace ComboStrap;
5use Psr\Log\LogLevel;
6
7/**
8 * Class Template
9 * @package ComboStrap
10 * https://stackoverflow.com/questions/17869964/replacing-string-within-php-file
11 */
12class Template
13{
14
15    const VARIABLE_PREFIX = "$";
16    const VARIABLE_PATTERN_CAPTURE_VARIABLE = "/(\\" . self::VARIABLE_PREFIX . "[\w]*)/im";
17    const VARIABLE_PATTERN_CAPTURE_NAME = "/\\" . self::VARIABLE_PREFIX . "([\w]*)/im";
18    const CANONICAL = "template";
19
20    protected $_string;
21    protected $_data = array();
22
23    public function __construct($string = null)
24    {
25        $this->_string = $string;
26    }
27
28    /**
29     * @param $string
30     * @return Template
31     */
32    public static function create($string)
33    {
34        return new Template($string);
35    }
36
37    public function set($key, $value)
38    {
39        $this->_data[$key] = $value;
40        return $this;
41    }
42
43    public function render(): string
44    {
45
46
47        $variablePattern = self::VARIABLE_PATTERN_CAPTURE_VARIABLE;
48        $splits = preg_split($variablePattern, $this->_string, -1, PREG_SPLIT_DELIM_CAPTURE);
49        $rendered = "";
50        foreach ($splits as $part) {
51            if (substr($part, 0, 1) === self::VARIABLE_PREFIX) {
52                $variable = trim(substr($part, 1));
53                if(isset($this->_data[$variable])) {
54                    $value = $this->_data[$variable];
55                } else  {
56                    LogUtility::msg("The variable ($variable) was not found in the data and has not been replaced", LogUtility::LVL_MSG_ERROR,self::CANONICAL);
57                    $value = $variable;
58                }
59            } else {
60                $value = $part;
61            }
62            $rendered .= $value;
63        }
64        return $rendered;
65
66    }
67
68    /**
69     *
70     * @return false|string
71     * @deprecated Just for demo, don't use because the input is not validated
72     *
73     */
74    public function renderViaEval()
75    {
76        extract($this->_data);
77        ob_start();
78        eval("echo $this->_string ;");
79        return ob_get_clean();
80    }
81
82    /**
83     * @return array - an array of variable name
84     */
85    public function getVariablesDetected(): array
86    {
87        $result = preg_match_all(self::VARIABLE_PATTERN_CAPTURE_NAME, $this->_string, $matches);
88        if ($result >= 1) {
89            return $matches[1];
90        } else {
91            return [];
92        }
93
94
95    }
96}
97