1
|
|
|
<?php namespace Wn\Generators\Argument; |
2
|
|
|
|
3
|
|
|
use Illuminate\Filesystem\Filesystem; |
4
|
|
|
use Wn\Generators\Argument\ArgumentFormat; |
5
|
|
|
use Wn\Generators\Exceptions\ArgumentFormatException; |
6
|
|
|
|
7
|
|
|
|
8
|
|
|
class ArgumentFormatLoader { |
9
|
|
|
|
10
|
|
|
protected $fs; |
11
|
|
|
|
12
|
|
|
protected $loaded; |
13
|
|
|
|
14
|
|
|
public function __construct(Filesystem $fs) |
15
|
|
|
{ |
16
|
|
|
$this->fs = $fs; |
17
|
|
|
$this->loaded = []; |
18
|
|
|
} |
19
|
|
|
|
20
|
|
|
public function load($name) |
21
|
|
|
{ |
22
|
|
|
if(! isset($this->loaded[$name])){ |
23
|
|
|
$path = __DIR__ . "/../../formats/{$name}.json"; |
24
|
|
|
$json = ""; |
25
|
|
|
try { |
26
|
|
|
$json = json_decode($this->fs->get($path)); |
27
|
|
|
} catch(\Exception $e) { |
28
|
|
|
throw new ArgumentFormatException("Unable to read the file '{$path}'"); |
29
|
|
|
} |
30
|
|
|
if (json_last_error() !== JSON_ERROR_NONE){ |
31
|
|
|
throw new ArgumentFormatException("Error while parsing the JSON file '{$path}'"); |
32
|
|
|
} |
33
|
|
|
$this->loaded[$name] = $this->buildFormat($json); |
34
|
|
|
} |
35
|
|
|
return $this->loaded[$name]; |
36
|
|
|
} |
37
|
|
|
|
38
|
|
|
protected function buildFormat($obj) |
39
|
|
|
{ |
40
|
|
|
return $this->fillFirstLevel($obj); |
41
|
|
|
} |
42
|
|
|
|
43
|
|
|
protected function fillFirstLevel($obj) |
44
|
|
|
{ |
45
|
|
|
return $this->fill($obj, true); |
46
|
|
|
} |
47
|
|
|
|
48
|
|
|
protected function fill($obj, $firstLevel = false) |
49
|
|
|
{ |
50
|
|
|
if (is_string($obj)) { |
51
|
|
|
return $this->fillString($obj, $firstLevel); |
52
|
|
|
} else { |
53
|
|
|
return $this->fillObject($obj, $firstLevel); |
54
|
|
|
} |
55
|
|
|
} |
56
|
|
|
|
57
|
|
|
protected function fillString($string, $firstLevel = false) |
58
|
|
|
{ |
59
|
|
|
list($name, $type, $isArray) = $this->parseName($string); |
60
|
|
|
|
61
|
|
|
$format = new ArgumentFormat; |
62
|
|
|
$format->name = $name; |
63
|
|
|
|
64
|
|
|
if ($isArray) { |
65
|
|
|
$format->type = 'array'; |
66
|
|
|
$subFormat = new ArgumentFormat; |
67
|
|
|
$subFormat->type = $type ?: 'string'; |
68
|
|
|
$format->format = $subFormat; |
69
|
|
|
} else { |
70
|
|
|
$format->type = 'string'; |
71
|
|
|
} |
72
|
|
|
|
73
|
|
View Code Duplication |
if ($firstLevel) { |
|
|
|
|
74
|
|
|
if ($format->type === 'object') { |
75
|
|
|
$format->separator = ':'; |
76
|
|
|
} elseif ($format->type === 'array') { |
77
|
|
|
$format->separator = ','; |
78
|
|
|
} |
79
|
|
|
} |
80
|
|
|
|
81
|
|
|
return $format; |
82
|
|
|
} |
83
|
|
|
|
84
|
|
|
protected function fillObject($obj, $firstLevel=false) |
85
|
|
|
{ |
86
|
|
|
$format = new ArgumentFormat; |
87
|
|
|
|
88
|
|
|
// Resolve type from name |
89
|
|
|
if (isset($obj->name)) { |
90
|
|
|
list($name, $type) = $this->parseName($obj->name); |
91
|
|
|
$format->name = $name; |
92
|
|
|
$format->type = $type; |
93
|
|
|
} |
94
|
|
|
|
95
|
|
|
// Fill type if set |
96
|
|
|
if (isset($obj->type)) { |
97
|
|
|
$format->type = $obj->type; |
98
|
|
|
} |
99
|
|
|
|
100
|
|
|
// Fill default if set |
101
|
|
|
if (isset($obj->default)) { |
102
|
|
|
$format->default = $obj->default; |
103
|
|
|
} |
104
|
|
|
|
105
|
|
|
// Set separator, default to ':' for objects and ',' for arrays in first level |
106
|
|
|
if (in_array($format->type, ['object', 'array'])) { |
107
|
|
View Code Duplication |
if (isset($obj->separator)) { |
|
|
|
|
108
|
|
|
$format->separator = $obj->separator; |
109
|
|
|
} elseif ($firstLevel) { |
110
|
|
|
$format->separator = ($format->type === 'object') ? ':':','; |
111
|
|
|
} |
112
|
|
|
} |
113
|
|
|
|
114
|
|
|
// Build format recursively |
115
|
|
|
if (isset($obj->fields)) { |
116
|
|
|
if ($firstLevel) { |
117
|
|
View Code Duplication |
if (is_array($obj->fields)) { |
|
|
|
|
118
|
|
|
$format->format = array_map([$this, 'fillFirstLevel'], $obj->fields); |
119
|
|
|
} else { |
120
|
|
|
$format->format = $this->fill($obj->fields, true); |
121
|
|
|
} |
122
|
|
View Code Duplication |
} else { |
|
|
|
|
123
|
|
|
if (is_array($obj->fields)) { |
124
|
|
|
$format->format = array_map([$this, 'fill'], $obj->fields); |
125
|
|
|
} else { |
126
|
|
|
$format->format = $this->fill($obj->fields); |
127
|
|
|
} |
128
|
|
|
} |
129
|
|
|
} |
130
|
|
|
|
131
|
|
|
return $format; |
132
|
|
|
} |
133
|
|
|
|
134
|
|
|
protected function parseName($name) |
135
|
|
|
{ |
136
|
|
|
$pattern = '/^(?P<attr>\w+)(\[(?P<type>\w+)?\])?/'; |
137
|
|
|
preg_match($pattern, $name, $matches); |
138
|
|
|
|
139
|
|
|
$attr = $matches['attr']; |
140
|
|
|
$type = empty($matches['type']) ? null : $matches['type']; |
141
|
|
|
$isArray = (isset($matches[2][0]) && $matches[2][0] === '['); |
142
|
|
|
|
143
|
|
|
return [$attr, $type, $isArray]; |
144
|
|
|
} |
145
|
|
|
|
146
|
|
|
} |
147
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.