xref: /template/strap/ComboStrap/Template.php (revision 04fd306c7c155fa133ebb3669986875d65988276)
137748cd8SNickeau<?php
237748cd8SNickeau
337748cd8SNickeau
437748cd8SNickeaunamespace ComboStrap;
5*04fd306cSNickeau
61fa8c418SNickeau
737748cd8SNickeau/**
837748cd8SNickeau * Class Template
937748cd8SNickeau * @package ComboStrap
1037748cd8SNickeau * https://stackoverflow.com/questions/17869964/replacing-string-within-php-file
1137748cd8SNickeau */
1237748cd8SNickeauclass Template
1337748cd8SNickeau{
1437748cd8SNickeau
15*04fd306cSNickeau    public const DOLLAR_VARIABLE_PREFIX = "$";
161fa8c418SNickeau
17*04fd306cSNickeau    public const DOLLAR_ESCAPE = '\\';
18*04fd306cSNickeau
19*04fd306cSNickeau    public const CAPTURE_PATTERN_SHORT = Template::DOLLAR_ESCAPE . Template::DOLLAR_VARIABLE_PREFIX . self::VARIABLE_NAME_EXPRESSION;
20*04fd306cSNickeau    public const CAPTURE_PATTERN_LONG = Template::DOLLAR_ESCAPE . Template::LONG_PREFIX . "[^}\r\n]+" . self::LONG_EXIT;
21*04fd306cSNickeau
22*04fd306cSNickeau
23*04fd306cSNickeau    const CANONICAL = "variable-template";
24*04fd306cSNickeau    public const LONG_PREFIX = self::DOLLAR_VARIABLE_PREFIX . self::LONG_ENTER;
25*04fd306cSNickeau    public const LONG_EXIT = '}';
26*04fd306cSNickeau    const LONG_ENTER = '{';
27*04fd306cSNickeau    const VARIABLE_NAME_EXPRESSION = "[A-Za-z0-9_]+";
28*04fd306cSNickeau    const LONG_VARIABLE_NAME_CAPTURE_EXPRESSION = self::DOLLAR_ESCAPE . self::LONG_PREFIX . '\s*(' . self::VARIABLE_NAME_EXPRESSION . ')[^\r\n]*' . self::LONG_EXIT;
29*04fd306cSNickeau
30*04fd306cSNickeau
31*04fd306cSNickeau    protected string $_string;
32*04fd306cSNickeau    protected array $_data = array();
3337748cd8SNickeau
3437748cd8SNickeau    public function __construct($string = null)
3537748cd8SNickeau    {
3637748cd8SNickeau        $this->_string = $string;
3737748cd8SNickeau    }
3837748cd8SNickeau
3937748cd8SNickeau    /**
4037748cd8SNickeau     * @param $string
4137748cd8SNickeau     * @return Template
4237748cd8SNickeau     */
43*04fd306cSNickeau    public static function create($string): Template
4437748cd8SNickeau    {
4537748cd8SNickeau        return new Template($string);
4637748cd8SNickeau    }
4737748cd8SNickeau
48*04fd306cSNickeau    public static function toValidVariableName(string $name)
49*04fd306cSNickeau    {
50*04fd306cSNickeau        return str_replace("-", "", $name);
51*04fd306cSNickeau    }
52*04fd306cSNickeau
53*04fd306cSNickeau    public function setProperty($key, $value): Template
5437748cd8SNickeau    {
5537748cd8SNickeau        $this->_data[$key] = $value;
5637748cd8SNickeau        return $this;
5737748cd8SNickeau    }
5837748cd8SNickeau
591fa8c418SNickeau    public function render(): string
6037748cd8SNickeau    {
6137748cd8SNickeau
62*04fd306cSNickeau        $pattern = '/' .
63*04fd306cSNickeau            '(' . self::DOLLAR_ESCAPE . self::DOLLAR_VARIABLE_PREFIX . self::VARIABLE_NAME_EXPRESSION . ')' .
64*04fd306cSNickeau            '|' .
65*04fd306cSNickeau            '(' . self::DOLLAR_ESCAPE . self::LONG_PREFIX . '\s*' . self::VARIABLE_NAME_EXPRESSION . '[^\r\n]*' . self::LONG_EXIT . ')' .
66*04fd306cSNickeau            '/im';
67*04fd306cSNickeau        $splits = preg_split($pattern, $this->_string, -1, PREG_SPLIT_DELIM_CAPTURE);
6837748cd8SNickeau        $rendered = "";
6937748cd8SNickeau        foreach ($splits as $part) {
70*04fd306cSNickeau            if (substr($part, 0, 1) === self::DOLLAR_VARIABLE_PREFIX) {
71*04fd306cSNickeau                if (substr($part, 1, 1) === self::LONG_ENTER) {
72*04fd306cSNickeau                    $matches = [];
73*04fd306cSNickeau                    preg_match('/' . self::LONG_VARIABLE_NAME_CAPTURE_EXPRESSION . '/im', $part, $matches);
74*04fd306cSNickeau                    $variable = $matches[1];
75*04fd306cSNickeau                } else {
7637748cd8SNickeau                    $variable = trim(substr($part, 1));
77*04fd306cSNickeau                }
78*04fd306cSNickeau                if (array_key_exists($variable, $this->_data)) {
7937748cd8SNickeau                    $value = $this->_data[$variable];
8037748cd8SNickeau                } else {
81*04fd306cSNickeau                    LogUtility::warning("The variable ($variable) was not found in the data and has not been replaced", self::CANONICAL);
821fa8c418SNickeau                    $value = $variable;
831fa8c418SNickeau                }
841fa8c418SNickeau            } else {
8537748cd8SNickeau                $value = $part;
8637748cd8SNickeau            }
8737748cd8SNickeau            $rendered .= $value;
8837748cd8SNickeau        }
8937748cd8SNickeau        return $rendered;
9037748cd8SNickeau
9137748cd8SNickeau    }
9237748cd8SNickeau
9337748cd8SNickeau    /**
9437748cd8SNickeau     *
9537748cd8SNickeau     * @return false|string
9637748cd8SNickeau     * @deprecated Just for demo, don't use because the input is not validated
9737748cd8SNickeau     *
9837748cd8SNickeau     */
9937748cd8SNickeau    public function renderViaEval()
10037748cd8SNickeau    {
10137748cd8SNickeau        extract($this->_data);
10237748cd8SNickeau        ob_start();
10337748cd8SNickeau        eval("echo $this->_string ;");
10437748cd8SNickeau        return ob_get_clean();
10537748cd8SNickeau    }
1061fa8c418SNickeau
1071fa8c418SNickeau    /**
1081fa8c418SNickeau     * @return array - an array of variable name
1091fa8c418SNickeau     */
1101fa8c418SNickeau    public function getVariablesDetected(): array
1111fa8c418SNickeau    {
112*04fd306cSNickeau        /** @noinspection RegExpUnnecessaryNonCapturingGroup */
113*04fd306cSNickeau        $pattern = '/' .
114*04fd306cSNickeau            '(?:' . self::DOLLAR_ESCAPE . self::DOLLAR_VARIABLE_PREFIX . '(' . self::VARIABLE_NAME_EXPRESSION . '))' .
115*04fd306cSNickeau            '|' .
116*04fd306cSNickeau            '(?:' . self::LONG_VARIABLE_NAME_CAPTURE_EXPRESSION . ')' .
117*04fd306cSNickeau            '/im';
118*04fd306cSNickeau        $result = preg_match_all($pattern, $this->_string, $matches);
1191fa8c418SNickeau        if ($result >= 1) {
120*04fd306cSNickeau            $returnedMatch = [];
121*04fd306cSNickeau            $firstExpressionMatches = $matches[1];
122*04fd306cSNickeau            $secondExpressionMatches = $matches[2];
123*04fd306cSNickeau            foreach ($firstExpressionMatches as $key => $match) {
124*04fd306cSNickeau                if (empty($match)) {
125*04fd306cSNickeau                    $returnedMatch[] = $secondExpressionMatches[$key];
126*04fd306cSNickeau                    continue;
127*04fd306cSNickeau                }
128*04fd306cSNickeau                $returnedMatch[] = $match;
129*04fd306cSNickeau            }
130*04fd306cSNickeau            return $returnedMatch;
1311fa8c418SNickeau        } else {
1321fa8c418SNickeau            return [];
1331fa8c418SNickeau        }
1341fa8c418SNickeau
135*04fd306cSNickeau    }
136*04fd306cSNickeau
137*04fd306cSNickeau    public function setProperties(array $properties): Template
138*04fd306cSNickeau    {
139*04fd306cSNickeau        foreach ($properties as $key => $val) {
140*04fd306cSNickeau            $this->setProperty($key, $val);
141*04fd306cSNickeau        }
142*04fd306cSNickeau        return $this;
1431fa8c418SNickeau
1441fa8c418SNickeau    }
145*04fd306cSNickeau
14637748cd8SNickeau}
147