Passed
Pull Request — master (#1)
by Jitendra
01:21
created

PadsJson::padStack()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 9
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 4
nc 3
nop 1
dl 0
loc 9
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Ahc\Json;
4
5
/**
6
 * Attempts to fix truncated JSON by padding contextual counterparts at the end.
7
 *
8
 * @author   Jitendra Adhikari <[email protected]>
9
 * @license  MIT
10
 *
11
 * @internal
12
 *
13
 * @link     https://github.com/adhocore/php-json-fixer
14
 */
15
trait PadsJson
16
{
17
    public function pad($tmpJson)
18
    {
19
        if (!$this->inStr) {
20
            $tmpJson = \rtrim($tmpJson, ',');
21
            while ($this->lastToken() === ',') {
0 ignored issues
show
Bug introduced by
It seems like lastToken() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

21
            while ($this->/** @scrutinizer ignore-call */ lastToken() === ',') {
Loading history...
22
                $this->popToken();
0 ignored issues
show
Bug introduced by
It seems like popToken() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

22
                $this->/** @scrutinizer ignore-call */ 
23
                       popToken();
Loading history...
23
            }
24
        }
25
26
        $tmpJson = $this->padLiteral($tmpJson);
27
        $tmpJson = $this->padObject($tmpJson);
28
29
        return $this->padStack($tmpJson);
30
    }
31
32
    protected function padLiteral($tmpJson)
33
    {
34
        if ($this->inStr) {
35
            return $tmpJson;
36
        }
37
38
        $match = \preg_match('/(tr?u?e?|fa?l?s?e|nu?l?l?)$/', $tmpJson, $matches);
39
40
        if (!$match || null === $literal = $this->maybeLiteral($matches[1])) {
0 ignored issues
show
Bug introduced by
It seems like maybeLiteral() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

40
        if (!$match || null === $literal = $this->/** @scrutinizer ignore-call */ maybeLiteral($matches[1])) {
Loading history...
41
            return $tmpJson;
42
        }
43
44
        return \substr($tmpJson, 0, 0 - \strlen($matches[1])) . $literal;
45
    }
46
47
    protected function padStack($tmpJson)
48
    {
49
        foreach (\array_reverse($this->stack, true) as $index => $token) {
50
            if (isset($this->pairs[$token])) {
51
                $tmpJson .= $this->pairs[$token];
52
            }
53
        }
54
55
        return $tmpJson;
56
    }
57
58
    protected function padObject($tmpJson)
59
    {
60
        if (!$this->objectNeedsPadding($tmpJson)) {
61
            return $tmpJson;
62
        }
63
64
        $part = \substr($tmpJson, $this->objectPos + 1);
65
        if (\preg_match('/(\s*\"[^"]+\"\s*:\s*[^,]+,?)+$/', $part, $matches)) {
66
            return $tmpJson;
67
        }
68
69
        if ($this->inStr) {
70
            $tmpJson .= '"';
71
        }
72
73
        $tmpJson = $this->padIf($tmpJson, ':');
74
        $tmpJson = $tmpJson . $this->missingValue;
75
76
        if ($this->lastToken() === '"') {
77
            $this->popToken();
78
        }
79
80
        return $tmpJson;
81
    }
82
83
    protected function objectNeedsPadding($tmpJson)
84
    {
85
        $last  = \substr($tmpJson, -1);
86
        $empty = $last === '{' && !$this->inStr;
87
88
        return !$empty && $this->arrayPos < $this->objectPos;
89
    }
90
91
    protected function padString($string)
92
    {
93
        $last  = \substr($string, -1);
94
        $last2 = \substr($string, -2);
95
96
        if ($last2 === '\"' || $last !== '"') {
97
            return $string . '"';
98
        }
99
100
        // @codeCoverageIgnoreStart
101
        return null;
102
        // @codeCoverageIgnoreEnd
103
    }
104
105
    protected function padIf($string, $substr)
106
    {
107
        if (\substr($string, 0 - \strlen($substr)) !== $substr) {
108
            return $string . $substr;
109
        }
110
111
        return $string;
112
    }
113
}
114