Passed
Pull Request — dev (#27)
by
unknown
03:20
created

MarkerParser::matchMarkers()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 14
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 10
nc 1
nop 1
dl 0
loc 14
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
/*
4
 * Copyright (C) 2017
5
 * Nathan Boiron <[email protected]>
6
 * Romain Canon <[email protected]>
7
 *
8
 * This file is part of the TYPO3 NotiZ project.
9
 * It is free software; you can redistribute it and/or modify it
10
 * under the terms of the GNU General Public License, either
11
 * version 3 of the License, or any later version.
12
 *
13
 * For the full copyright and license information, see:
14
 * http://www.gnu.org/licenses/gpl-3.0.html
15
 */
16
17
namespace CuyZ\Notiz\Property\Service;
18
19
use CuyZ\Notiz\Domain\Property\Marker;
20
use TYPO3\CMS\Extbase\Reflection\ObjectAccess;
21
22
/**
23
 * Helper class to parse markers and replace them in a given string.
24
 */
25
class MarkerParser
26
{
27
    /**
28
     * @param string $string
29
     * @param Marker[] $markers
30
     * @return string
31
     */
32
    public function replaceMarkers($string, array $markers)
33
    {
34
        if (empty($markers)) {
35
            return $string;
36
        }
37
38
        $markers = $this->keyMarkersByName($markers);
39
40
        list($identifiers, $variables, $roots) = $this->matchMarkers($string);
41
42
        if (empty($identifiers)) {
43
            return $string;
44
        }
45
46
        $replacePairs = [];
47
48
        foreach ($variables as $index => $variable) {
49
            $identifier = $identifiers[$index];
50
            $root = $roots[$index];
51
            $marker = $markers[$root];
52
53
            $value = $this->getVariableValue($variable, $root, $marker);
54
55
            $replacePairs[$identifier] = $value;
56
        }
57
58
        return strtr($string, $replacePairs);
59
    }
60
61
    /**
62
     * This will set each marker's name as the array key
63
     *
64
     * @param array $markers
65
     * @return array
66
     */
67
    private function keyMarkersByName(array $markers)
68
    {
69
        $aux = [];
70
71
        // This will avoid looping on markers for each variable
72
        foreach ($markers as $marker) {
73
            $aux[$marker->getName()] = $marker;
74
        }
75
76
        return $aux;
77
    }
78
79
    /**
80
     * This method will find all markers in the string
81
     *
82
     * @param $string
83
     * @return array
84
     */
85
    private function matchMarkers($string)
86
    {
87
        preg_match_all(
88
    '/{
89
                (
90
                    ([a-z]+[a-z0-1]*)           # The root variable
91
                    (?:\.[a-z]+[a-z0-1]*)*      # The other parts
92
                )
93
            }/xi',
94
            $string,
95
            $matches
96
        );
97
98
        return $matches;
99
    }
100
101
    /**
102
     * @param string $variable
103
     * @param string $root
104
     * @param Marker $marker
105
     * @return mixed
106
     */
107
    protected function getVariableValue($variable, $root, Marker $marker)
108
    {
109
        // We need to have the root name to allow the ObjectAccess class to
110
        // retrieve the value.
111
        $target = [
112
            $root => $marker->getValue(),
113
        ];
114
115
        return ObjectAccess::getPropertyPath($target, $variable);
116
    }
117
}
118