RegexReplacer   A
last analyzed

Complexity

Total Complexity 15

Size/Duplication

Total Lines 100
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
eloc 46
c 1
b 0
f 1
dl 0
loc 100
rs 10
wmc 15

7 Methods

Rating   Name   Duplication   Size   Complexity  
A replaceMatches() 0 17 2
A getUri() 0 10 2
A bodyConditionIsRegex() 0 4 2
A replaceMatchesInBody() 0 18 3
A fillWithUrlMatches() 0 15 2
A fillWithBodyMatches() 0 15 2
A urlConditionIsRegex() 0 4 2
1
<?php
2
/**
3
 * This file is part of Phiremock.
4
 *
5
 * Phiremock is free software: you can redistribute it and/or modify
6
 * it under the terms of the GNU Lesser General Public License as published by
7
 * the Free Software Foundation, either version 3 of the License, or
8
 * (at your option) any later version.
9
 *
10
 * Phiremock is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with Phiremock.  If not, see <http://www.gnu.org/licenses/>.
17
 */
18
19
namespace Mcustiel\Phiremock\Server\Utils\Strategies\Utils;
20
21
use Mcustiel\Phiremock\Domain\Condition\MatchersEnum;
22
use Mcustiel\Phiremock\Domain\Expectation;
23
use Psr\Http\Message\ServerRequestInterface;
24
25
class RegexReplacer
26
{
27
    const PLACEHOLDER_BODY = 'body';
28
    const PLACEHOLDER_URL = 'url';
29
30
    public function fillWithBodyMatches(
31
        Expectation $expectation,
32
        ServerRequestInterface $httpRequest,
33
        string $text
34
    ): string {
35
        if ($this->bodyConditionIsRegex($expectation)) {
36
            $text = $this->replaceMatches(
37
                self::PLACEHOLDER_BODY,
38
                $expectation->getRequest()->getBody()->getValue()->asString(),
39
                $httpRequest->getBody()->__toString(),
40
                $text
41
            );
42
        }
43
44
        return $text;
45
    }
46
47
    public function fillWithUrlMatches(
48
        Expectation $expectation,
49
        ServerRequestInterface $httpRequest,
50
        string $text
51
    ): string {
52
        if ($this->urlConditionIsRegex($expectation)) {
53
            return $this->replaceMatches(
54
                self::PLACEHOLDER_URL,
55
                $expectation->getRequest()->getUrl()->getValue()->asString(),
56
                $this->getUri($httpRequest),
57
                $text
58
            );
59
        }
60
61
        return $text;
62
    }
63
64
    private function getUri(ServerRequestInterface $httpRequest): string
65
    {
66
        $path = ltrim($httpRequest->getUri()->getPath(), '/');
67
        $query = $httpRequest->getUri()->getQuery();
68
        $return = '/' . $path;
69
        if ($query) {
70
            $return .= '?' . $httpRequest->getUri()->getQuery();
71
        }
72
73
        return $return;
74
    }
75
76
    private function urlConditionIsRegex(Expectation $expectation): bool
77
    {
78
        return $expectation->getRequest()->getUrl()
79
            && MatchersEnum::MATCHES === $expectation->getRequest()->getUrl()->getMatcher()->getName();
80
    }
81
82
    private function bodyConditionIsRegex(Expectation $expectation): bool
83
    {
84
        return $expectation->getRequest()->getBody()
85
            && MatchersEnum::MATCHES === $expectation->getRequest()->getBody()->getMatcher()->getName();
86
    }
87
88
    private function replaceMatches(
89
        string $type, string $pattern, string $subject, string $destination): string
90
    {
91
        $matches = [];
92
93
        $matchCount = preg_match_all(
94
            $pattern,
95
            $subject,
96
            $matches
97
        );
98
        if ($matchCount > 0) {
99
            // we don't need full matches
100
            unset($matches[0]);
101
            $destination = $this->replaceMatchesInBody($matches, $type, $destination);
102
        }
103
104
        return $destination;
105
    }
106
107
    private function replaceMatchesInBody(array $matches, string $type, string $responseBody): string
108
    {
109
        $search = [];
110
        $replace = [];
111
112
        foreach ($matches as $matchGroupId => $matchGroup) {
113
            // add first element as replacement for $(type.index)
114
            $search[] = "\${{$type}.{$matchGroupId}}";
115
            $replace[] = reset($matchGroup);
116
            foreach ($matchGroup as $matchId => $match) {
117
                // fix index to start with 1 instead of 0
118
                ++$matchId;
119
                $search[] = "\${{$type}.{$matchGroupId}.{$matchId}}";
120
                $replace[] = $match;
121
            }
122
        }
123
124
        return str_replace($search, $replace, $responseBody);
125
    }
126
}
127