MarkerParser::matchMarkers()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 14
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 1
eloc 10
c 2
b 0
f 0
nc 1
nop 1
dl 0
loc 14
rs 9.9332
1
<?php
2
declare(strict_types=1);
3
4
/*
5
 * Copyright (C)
6
 * Nathan Boiron <[email protected]>
7
 * Romain Canon <[email protected]>
8
 *
9
 * This file is part of the TYPO3 NotiZ project.
10
 * It is free software; you can redistribute it and/or modify it
11
 * under the terms of the GNU General Public License, either
12
 * version 3 of the License, or any later version.
13
 *
14
 * For the full copyright and license information, see:
15
 * http://www.gnu.org/licenses/gpl-3.0.html
16
 */
17
18
namespace CuyZ\Notiz\Core\Property\Service;
19
20
use CuyZ\Notiz\Domain\Property\Marker;
21
use TYPO3\CMS\Core\SingletonInterface;
22
use TYPO3\CMS\Extbase\Reflection\ObjectAccess;
0 ignored issues
show
Bug introduced by
The type TYPO3\CMS\Extbase\Reflection\ObjectAccess was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
23
24
/**
25
 * Helper class to parse markers and replace them in a given string.
26
 */
27
class MarkerParser implements SingletonInterface
28
{
29
    /**
30
     * @param string $string
31
     * @param Marker[] $markers
32
     * @return string
33
     */
34
    public function replaceMarkers(string $string, array $markers): string
35
    {
36
        if (empty($markers)) {
37
            return $string;
38
        }
39
40
        $markers = $this->keyMarkersByName($markers);
41
42
        list($identifiers, $variables, $roots) = $this->matchMarkers($string);
43
44
        if (empty($identifiers)) {
45
            return $string;
46
        }
47
48
        $replacePairs = [];
49
50
        foreach ($variables as $index => $variable) {
51
            $identifier = $identifiers[$index];
52
            $root = $roots[$index];
53
54
            $replacePairs[$identifier] = isset($markers[$root])
55
                ? $this->getVariableValue($variable, $root, $markers[$root])
56
                : '';
57
        }
58
59
        return strtr($string, $replacePairs);
60
    }
61
62
    /**
63
     * This will set each marker's name as the array key
64
     *
65
     * @param array $markers
66
     * @return array
67
     */
68
    private function keyMarkersByName(array $markers): array
69
    {
70
        $aux = [];
71
72
        // This will avoid looping on markers for each variable
73
        foreach ($markers as $marker) {
74
            $aux[$marker->getName()] = $marker;
75
        }
76
77
        return $aux;
78
    }
79
80
    /**
81
     * This method will find all markers in the string
82
     *
83
     * @param $string
84
     * @return array
85
     */
86
    private function matchMarkers($string): array
87
    {
88
        preg_match_all(
89
            '/{
90
                (
91
                    ([a-z]+[a-z0-9-_]*)           # The root variable
92
                    (?:\.[a-z0-9-_]+)*            # The other parts
93
                )
94
            }/xi',
95
            $string,
96
            $matches
97
        );
98
99
        return $matches;
100
    }
101
102
    /**
103
     * @param string $variable
104
     * @param string $root
105
     * @param Marker $marker
106
     * @return mixed
107
     */
108
    protected function getVariableValue(string $variable, string $root, Marker $marker)
109
    {
110
        // We need to have the root name to allow the ObjectAccess class to
111
        // retrieve the value.
112
        $target = [
113
            $root => $marker->getValue(),
114
        ];
115
116
        return ObjectAccess::getPropertyPath($target, $variable);
117
    }
118
}
119