Passed
Push — master ( f519e1...ef65fe )
by Brian
02:51
created

Parser::doProcess()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 18
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 3.009

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 9
c 1
b 0
f 0
dl 0
loc 18
ccs 9
cts 10
cp 0.9
rs 9.9666
cc 3
nc 3
nop 1
crap 3.009
1
<?php
2
3
namespace Bmatovu\Ussd;
4
5
use Bmatovu\Ussd\Contracts\AnswerableTag;
6
use Bmatovu\Ussd\Traits\ParserUtils;
7
8
class Parser
9
{
10
    use ParserUtils;
0 ignored issues
show
introduced by
The trait Bmatovu\Ussd\Traits\ParserUtils requires some properties which are not provided by Bmatovu\Ussd\Parser: $tagName, $attributes, $nodeValue
Loading history...
11
12
    protected \DOMXPath $xpath;
13
    protected string $sessionId;
14
    protected Store $store;
15
16 5
    public function __construct(\DOMXPath $xpath, string $expression, string $sessionId, string $serviceCode = '')
17
    {
18 5
        $this->xpath = $xpath;
19
20
        // $config = Container::getInstance()->make('config');
21 5
        $store = config('ussd.cache.store', 'file');
22 5
        $ttl = config('ussd.cache.ttl', 120);
23 5
        $this->store = new Store($store, $ttl, $sessionId);
24
25 5
        if ($this->sessionExists($sessionId)) {
26 2
            return;
27
        }
28
29 3
        $serviceCode = $this->clean($serviceCode);
30 3
        $this->store->put('_session_id', $sessionId);
31 3
        $this->store->put('_service_code', $serviceCode);
32 3
        $this->store->put('_answer', $serviceCode);
33 3
        $this->store->put('_pre', '');
34 3
        $this->store->put('_exp', $expression);
35 3
        $this->store->put('_breakpoints', '[]');
36
    }
37
38
    public function setOptions(array $options): self
39
    {
40
        foreach ($options as $key => $value) {
41
            $this->store->put($key, $value);
42
        }
43
44
        return $this;
45
    }
46
47 5
    public function parse(?string $userInput = ''): string
48
    {
49
        // return $this->doParse($userInput);
50
51 5
        $answer = $this->getAnswer($userInput);
52
53 5
        \Illuminate\Support\Facades\Log::debug('__answers', [
54 5
            'old' => $this->store->get('_answer'),
55
            'input' => $userInput,
56
            'new' => $answer,
57
        ]);
58
59
        // return $output = $this->doParse($answer);
60
61 5
        $answers = explode('*', $answer);
62
63 5
        foreach ($answers as $answer) {
64 5
            $output = $this->doParse($answer);
65
        }
66
67 3
        return $output;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $output seems to be defined by a foreach iteration on line 63. Are you sure the iterator is never empty, otherwise this variable is not defined?
Loading history...
68
    }
69
70 5
    protected function doParse(?string $answer = ''): ?string
71
    {
72 5
        $this->doProcess($answer);
73
74 5
        $exp = $this->store->get('_exp');
75 5
        $node = $this->xpath->query($exp)->item(0);
76
77 5
        if (! $node) {
78 1
            $this->doBreak();
79
        }
80
81 5
        $output = $this->doRender();
82
83 3
        if (! $output) {
84 1
            return $this->doParse($answer);
85
        }
86
87 3
        return $output;
88
    }
89
90 5
    protected function doProcess(?string $answer): void
91
    {
92 5
        $pre = $this->store->get('_pre');
93
94 5
        if (! $pre) {
95 4
            return;
96
        }
97
98 2
        $preNode = $this->xpath->query($pre)->item(0);
99
100 2
        $tagName = $this->resolveTagName($preNode);
101 2
        $tag = $this->instantiateTag($tagName, [$preNode, $this->store]);
102
103 2
        if (! $tag instanceof AnswerableTag) {
104 2
            return;
105
        }
106
107
        $tag->process($answer);
108
    }
109
110 1
    protected function doBreak(): void
111
    {
112 1
        $exp = $this->store->get('_exp');
113
114 1
        $breakpoints = (array) json_decode((string) $this->store->get('_breakpoints'), true);
115
116 1
        if (! $breakpoints || ! isset($breakpoints[0][$exp])) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $breakpoints of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
117
            throw new \Exception('Missing tag');
118
        }
119
120 1
        $breakpoint = array_shift($breakpoints);
121 1
        $this->store->put('_exp', $breakpoint[$exp]);
122 1
        $this->store->put('_breakpoints', json_encode($breakpoints));
123
    }
124
125 5
    protected function doRender(): ?string
126
    {
127 5
        $exp = $this->store->get('_exp');
128
129 5
        $node = $this->xpath->query($exp)->item(0);
130
131 5
        $tagName = $this->resolveTagName($node);
132 5
        $tag = $this->instantiateTag($tagName, [$node, $this->store]);
133 4
        $output = $tag->handle();
134
135 3
        $exp = $this->store->get('_exp');
136 3
        $breakpoints = (array) json_decode((string) $this->store->get('_breakpoints'), true);
137
138 3
        if ($breakpoints && isset($breakpoints[0][$exp])) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $breakpoints of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
139
            $breakpoint = array_shift($breakpoints);
140
            $this->store->put('_exp', $breakpoint[$exp]);
141
            $this->store->put('_breakpoints', json_encode($breakpoints));
142
        }
143
144 3
        return $output;
145
    }
146
}
147