Passed
Push — master ( 71e346...ca9e15 )
by Brian
02:28
created

ParserUtils   A

Complexity

Total Complexity 20

Size/Duplication

Total Lines 120
Duplicated Lines 0 %

Test Coverage

Coverage 47.27%

Importance

Changes 4
Bugs 1 Features 0
Metric Value
wmc 20
eloc 47
c 4
b 1
f 0
dl 0
loc 120
ccs 26
cts 55
cp 0.4727
rs 10

10 Methods

Rating   Name   Duplication   Size   Complexity  
A sessionExists() 0 5 1
A __get() 0 3 1
A clean() 0 7 2
A translate() 0 16 3
A xpathFromStr() 0 7 1
A __set() 0 3 1
A resolveTagName() 0 11 2
A resolveTagClass() 0 18 3
A getAnswer() 0 21 5
A instantiateTag() 0 5 1
1
<?php
2
3
namespace Bmatovu\Ussd\Traits;
4
5
use Bmatovu\Ussd\Contracts\RenderableTag;
6
use Illuminate\Container\Container;
7
use Illuminate\Contracts\Config\Repository as ConfigRepository;
8
use Illuminate\Support\Str;
9
10
trait ParserUtils
11
{
12 1
    public function __get(string $key)
13
    {
14 1
        return $this->{$key};
15
    }
16
17
    public function __set(string $key, $value)
18
    {
19
        $this->{$key} = $value;
20
    }
21
22
    /**
23
     * @see https://stackoverflow.com/q/413071/2732184
24
     * @see https://www.regextester.com/97707
25
     */
26
    public function translate(string $text, string $pattern = '/[^{{\}\}]+(?=}})/'): string
27
    {
28
        preg_match_all($pattern, $text, $matches);
29
30
        if (0 === \count($matches[0])) {
31
            return $text;
32
        }
33
34
        $replace_vars = [];
35
36
        foreach ($matches[0] as $match) {
37
            $var = Str::slug($match, '_');
38
            $replace_vars["{{{$match}}}"] = $this->store->get("{$prefix}{$var}", "{{$var}}");
0 ignored issues
show
Bug Best Practice introduced by
The property store does not exist on Bmatovu\Ussd\Traits\ParserUtils. Since you implemented __get, consider adding a @property annotation.
Loading history...
Comprehensibility Best Practice introduced by
The variable $prefix seems to be never defined.
Loading history...
39
        }
40
41
        return strtr($text, $replace_vars);
42
    }
43
44
    protected function xpathFromStr(string $file): \DOMXPath
45
    {
46
        $doc = new \DOMDocument();
47
48
        $doc->load($file);
49
50
        return new \DOMXPath($doc);
51
    }
52
53 5
    protected function sessionExists(string $sessionId): bool
54
    {
55 5
        $preSessionId = $this->store->get('_session_id', '');
0 ignored issues
show
Bug Best Practice introduced by
The property store does not exist on Bmatovu\Ussd\Traits\ParserUtils. Since you implemented __get, consider adding a @property annotation.
Loading history...
56
57 5
        return $preSessionId === $sessionId;
58
    }
59
60
    protected function clean(string $code = ''): string
61
    {
62
        if (! $code) {
63
            return $code;
64
        }
65
66
        return rtrim(ltrim($code, '*'), '#');
67
    }
68
69 5
    protected function getAnswer(?string $userInput): ?string
70
    {
71 5
        if (! $userInput) {
72 5
            return '';
73
        }
74
75
        $preAnswer = $this->store->get('_answer', '');
0 ignored issues
show
Bug Best Practice introduced by
The property store does not exist on Bmatovu\Ussd\Traits\ParserUtils. Since you implemented __get, consider adding a @property annotation.
Loading history...
76
77
        $answer = $this->clean(str_replace($preAnswer, '', $userInput));
78
79
        if (! $answer) {
80
            return $answer;
81
        }
82
83
        if (! $preAnswer || Str::endsWith($preAnswer, '*')) {
84
            $this->store->append('_answer', "{$answer}*");
85
        } else {
86
            $this->store->append('_answer', "*{$answer}*");
87
        }
88
89
        return $answer;
90
    }
91
92 5
    protected function resolveTagName(\DOMNode $node): string
93
    {
94 5
        $tagName = $node->tagName;
95
96 5
        if ('action' !== strtolower($tagName)) {
97 5
            return Str::studly("{$tagName}Tag");
98
        }
99
100
        $tagName = $node->attributes->getNamedItem('name')->nodeValue;
0 ignored issues
show
Bug introduced by
The method getNamedItem() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

100
        $tagName = $node->attributes->/** @scrutinizer ignore-call */ getNamedItem('name')->nodeValue;

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
101
102
        return Str::studly("{$tagName}Action");
103
    }
104
105 5
    protected function resolveTagClass(string $tagName): string
106
    {
107 5
        $config = Container::getInstance()->make(ConfigRepository::class);
108 5
        $tagNs = $config->get('ussd.tag-ns', []);
109 5
        $actionNs = $config->get('ussd.action-ns', []);
110
111 5
        $namespaces = array_merge($tagNs, $actionNs);
112
113 5
        $fqcn = $tagName;
0 ignored issues
show
Unused Code introduced by
The assignment to $fqcn is dead and can be removed.
Loading history...
114
115 5
        foreach ($namespaces as $ns) {
116 5
            $fqcn = "{$ns}\\{$tagName}";
117 5
            if (class_exists($fqcn)) {
118 4
                return $fqcn;
119
            }
120
        }
121
122 1
        throw new \Exception("Missing class: {$tagName}");
123
    }
124
125 5
    protected function instantiateTag(string $tagName, array $args = []): RenderableTag
126
    {
127 5
        $fqcn = $this->resolveTagClass($tagName);
128
129 4
        return \call_user_func_array([new \ReflectionClass($fqcn), 'newInstance'], $args);
130
    }
131
}
132