Passed
Push — master ( 435178...db7453 )
by Francis
01:16 queued 10s
created

JSONP::recursive_scalar_key_build()   A

Complexity

Conditions 4
Paths 6

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 4
eloc 5
c 1
b 0
f 0
nc 6
nop 2
dl 0
loc 8
rs 10
1
<?php
2
declare(strict_types=1);
3
defined('BASEPATH') or exit('No direct script access allowed');
4
5
class JSONP
6
{
7
8
  private $data = null;
9
  private $buffer = null;
10
  private $pool = null;
11
  private $poolKey = null;
12
13
  const FIELD_REGEX = "/\w+/";
14
  const ARRAY_REGEX = "/^\w+\[/";
15
  const ALL_ARRAY_REGEX = "/^\w+\[\*\]/";
16
  const SPECIFIC_ARRAY_REGEX = "/^\w+\[\d+\]/";
17
  const RANGE_ARRAY_REGEX = "/^\w+\[(\d|):(\d|)\]/";
18
19
  /**
20
   * [parse description]
21
   * @param  [type] $data [description]
0 ignored issues
show
Documentation Bug introduced by
The doc comment [type] at position 0 could not be parsed: Unknown type name '[' at position 0 in [type].
Loading history...
22
   * @return bool         [description]
23
   */
24
  public function parse(&$data):bool
25
  {
26
    if (is_scalar($data)) {
27
      $this->data = json_decode($data);
28
      if ($this->data == null || !is_object($this->data)) {
29
        $this->data = null;
30
        return false;
31
      }
32
      return true;
33
    }
34
    if (is_array($data)) {
35
      $this->data =& $data;
36
      //var_dump($this->data);
37
      return true;
38
    }
39
    return false;
40
  }
41
  /**
42
   * [set description]
43
   * @param string $path  [description]
44
   * @param [type] $value [description]
0 ignored issues
show
Documentation Bug introduced by
The doc comment [type] at position 0 could not be parsed: Unknown type name '[' at position 0 in [type].
Loading history...
45
   */
46
  public function set(string $path, $value):void
47
  {
48
    $this->run_json_path($path);
49
    $this->buffer = $value;
50
  }
51
  /**
52
   * [get description]
53
   * @param  string $path [description]
54
   * @return [type]       [description]
0 ignored issues
show
Documentation Bug introduced by
The doc comment [type] at position 0 could not be parsed: Unknown type name '[' at position 0 in [type].
Loading history...
55
   */
56
  public function get(string $path)
57
  {
58
    $this->run_json_path($path);
59
60
    if ($this->pool == null) return $this->buffer;
61
62
    if ($this->poolKey == null) return $this->pool;
63
64
    if (is_scalar($this->poolKey)) {
65
      $values = [];
66
      $this->recursive_scalar_key_build($values, $this->pool);
67
      return $values;
68
    }
69
70
    // TODO: Recursive Array Key Build.
71
  }
72
  private function recursive_scalar_key_build(array &$values, &$pool):void
73
  {
74
    if (isset($pool[$this->poolKey])) {
75
      $values[] = $pool[$this->poolKey];
76
    }
77
    for ($x = 0; $x < count($pool); $x++) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
78
      if (is_array($pool[array_keys($pool)[$x]])) {
79
        $this->recursive_scalar_key_build($values, $pool[array_keys($pool)[$x]]);
80
      }
81
    }
82
  }
83
  /**
84
   * [get_reference description]
85
   * @param  string $path [description]
86
   * @return [type]       [description]
0 ignored issues
show
Documentation Bug introduced by
The doc comment [type] at position 0 could not be parsed: Unknown type name '[' at position 0 in [type].
Loading history...
87
   */
88
  public function &get_reference(string $path)
89
  {
90
    $this->run_json_path($path);
91
    return $this->buffer;
92
  }
93
  /**
94
   * [run_path description]
95
   * @param string $path [description]
96
   */
97
  private function run_json_path(string $path):void
98
  {
99
    $this->buffer =& $this->data;
100
    unset($this->pool);
101
    $this->pool = null;
102
    $this->poolKey = null;
103
    $steps = explode('.', $path);
104
    foreach ($steps as $loopIndex => $step) {
105
      switch ($step) {
106
        case '$':
107
        case '':
108
          continue;
109
        default:
110
          if ($this->exact_match(self::FIELD_REGEX, $step)) {
111
            if ($this->pool == null) {
112
              $this->buffer =& $this->buffer[$step];
113
            } else {
114
              $this->poolKey = $step;
115
            }
116
            if ($loopIndex == count($steps) - 1) { break; } else { continue; }
117
          }
118
          if (preg_match(self::ARRAY_REGEX, $step)) {
119
            if (preg_match(self::SPECIFIC_ARRAY_REGEX, $step)) {
120
              list($key, $index) = $this->parse_specific_array_notation($step);
121
              if ($this->pool == null) {
122
                $this->buffer =& $this->buffer[$key][$index];
123
              } else {
124
                $this->poolKey = [$key, $index];
125
              }
126
              if ($loopIndex == count($steps) - 1) { break; } else { continue; }
127
            }
128
            if ($step == '[*]' || $step == '*') {
129
              $this->pool =& $this->buffer[$this->get_key_from_notation($step)];
130
              if ($loopIndex == count($steps) - 1) { break; } else { continue; }
131
            }
132
            if (preg_match(self::ALL_ARRAY_REGEX, $step)) {
133
              $this->pool =& $this->buffer[$this->get_key_from_notation($step)];
134
              if ($loopIndex == count($steps) - 1) { break; } else { continue; }
135
            }
136
          }
137
      }
138
    }
139
  }
140
  /**
141
   * [exact_match description]
142
   * @param  string $regex    [description]
143
   * @param  [type] $haystack [description]
0 ignored issues
show
Documentation Bug introduced by
The doc comment [type] at position 0 could not be parsed: Unknown type name '[' at position 0 in [type].
Loading history...
144
   * @return bool             [description]
145
   */
146
  private function exact_match(string $regex, $haystack):bool
147
  {
148
    preg_match($regex, $haystack, $matches);
149
    return strlen($matches[0]) == strlen($haystack);
150
  }
151
  /**
152
   * [get_key_from_notation description]
153
   * @param  string $notation [description]
154
   * @return string           [description]
155
   */
156
  private function get_key_from_notation(string $notation):string
157
  {
158
    preg_match("/\w+/", $notation, $matches);
159
    return $matches[0];
160
  }
161
  /**
162
   * [parse_specific_array_notation description]
163
   * @param  string $notation [description]
164
   * @return array            [description]
165
   */
166
  private function parse_specific_array_notation(string $notation):array
167
  {
168
    preg_match("/\w+/", $notation, $matches);
169
    $key = $matches[0];
170
    $notation = preg_replace(self::ARRAY_REGEX, '', $notation);
171
    $notation = str_replace(']', '', $notation);
172
    return [$key, $notation];
173
  }
174
}
175