Completed
Push — master ( 471861...67ffab )
by Russell
02:40
created

JSONBackend::matchOnPath()   C

Complexity

Conditions 11
Paths 10

Size

Total Lines 40
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 0 Features 2
Metric Value
c 3
b 0
f 2
dl 0
loc 40
rs 5.2653
cc 11
eloc 22
nc 10
nop 0

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/**
4
 * DB backend for use with the {@link JSONText} DB field. Allows us to use DB-specific JSON query syntax within
5
 * the module.
6
 * 
7
 * @package silverstripe-jsontext
8
 * @subpackage models
9
 * @author Russell Michell <[email protected]>
10
 */
11
12
namespace JSONText\Backends;
13
14
use JSONText\Exceptions\JSONTextException;
15
use JSONText\Fields\JSONText;
16
17
class JSONBackend
18
{
19
    /**
20
     * @var mixed
21
     */
22
    protected $key;
23
24
    /**
25
     * @var mixed
26
     */
27
    protected $val;
28
29
    /**
30
     * @var int
31
     */
32
    protected $idx;
33
    
34
    /**
35
     * @var string
36
     */
37
    protected $operand;
38
39
    /**
40
     * @var JSONText
41
     */
42
    protected $jsonText;
43
44
    /**
45
     * JSONBackend constructor.
46
     * 
47
     * @param mixed $key
48
     * @param mixed $val
49
     * @param int $idx
50
     * @param string $operand
51
     * @param JSONText $jsonText
52
     */
53
    public function __construct($key, $val, $idx, $operand, $jsonText)
54
    {
55
        $this->key = $key;
56
        $this->val = $val;
57
        $this->idx = $idx;
58
        $this->operand = $operand;
59
        $this->jsonText = $jsonText;
60
    }
61
    
62
    /**
63
     * Match on keys by INT.
64
     *
65
     * @return array
66
     */
67
    public function matchIfKeyIsInt()
68
    {
69
        if (is_int($this->operand) && $this->idx === $this->operand) {
70
            return [$this->key => $this->val];
71
        }
72
        
73
        return [];
74
    }
75
76
    /**
77
     * Match on keys by STRING.
78
     *
79
     * @return array
80
     */
81
    public function matchIfKeyIsStr()
82
    {
83
        // operand can be a numeric string if it wants here
84
        if (is_string($this->operand) && $this->key === $this->operand) {
85
            return [$this->key => $this->val];
86
        }
87
88
        return [];
89
    }
90
91
    /**
92
     * Match on path. If >1 matches are found, an indexed array of all matches is returned.
93
     *
94
     * @return array
95
     * @throws \JSONText\Exceptions\JSONTextException
96
     */
97
    public function matchOnPath()
98
    {
99
        if (!is_string($this->operand) || !$this->jsonText->isJson($this->operand)) {
100
            $msg = 'Invalid JSON passed as operand on RHS.';
101
            throw new JSONTextException($msg);
102
        }
103
        
104
        $operandAsArray = $this->jsonText->toArray($this->operand);
105
        
106
        // Empty is OK..could've been accidental...
107
        if (!count($operandAsArray)) {
108
            return [];
109
        }
110
111
        $keys = array_keys($operandAsArray);
112
        if (count($keys) >1) {
113
            $msg = 'Sorry. I can\'t handle complex operands.';
114
            throw new JSONTextException($msg);
115
        }
116
117
        $vals = array_values($operandAsArray);
118
        if (count($vals) >1) {
119
            $msg = 'Sorry. I can\'t handle complex operands.';
120
            throw new JSONTextException($msg);
121
        }
122
        
123
        // TODO Move this back to JSONText no use in iterating twice over source data 
124
        $data = [];
125
        foreach ($this->jsonText->getValueAsIterable() as $sourceKey => $sourceVal) {
126
            if ($keys[0] === $sourceKey && is_array($sourceVal) && !empty($sourceVal[$vals[0]])) {
127
                $data[] = $sourceVal[$vals[0]];
128
            }
129
        }
130
131
        if (count($data) === 1) {
132
            return $data[0];
133
        }
134
135
        return $data;
136
    }
137
    
138
}
139