YmlProvider::bestValue()   A
last analyzed

Complexity

Conditions 6
Paths 6

Size

Total Lines 23
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
eloc 12
nc 6
nop 1
dl 0
loc 23
rs 9.2222
c 0
b 0
f 0
1
<?php
2
3
namespace Sunnysideup\ConfigManager\View;
4
5
use SilverStripe\ORM\ArrayList;
6
use SilverStripe\View\ArrayData;
7
use SilverStripe\View\ViewableData;
8
use Sunnysideup\ConfigManager\Api\ConfigList;
9
use Symfony\Component\Yaml\Yaml;
10
11
class YmlProvider extends ViewableData
12
{
13
    protected $vendorName = '';
14
15
    protected $packageName = '';
16
17
    protected $locationFilter = '';
18
19
    protected $data = [];
20
21
    protected $filteredData = [];
22
23
    protected $dataAsObject;
24
25
    private static $model_fields = [
26
        'db',
27
        'has_one',
28
        'belongs_to',
29
        'has_many',
30
        'many_many',
31
        'many_many_extraFields',
32
        'belongs_many_many',
33
    ];
34
35
    private static $excluded_properties = [
36
        'db',
37
        'casting',
38
        'has_one',
39
        'belongs_to',
40
        'has_many',
41
        'many_many',
42
        'many_many_extraFields',
43
        'belongs_many_many',
44
        'allowed_actions',
45
    ];
46
47
    public function getYmlForLocation(string $locationFilter): string
48
    {
49
        $this->locationFilter = $locationFilter;
50
        $this->data = (new ConfigList())->getListOfConfigs();
51
        foreach ($this->data as $key => $item) {
52
            if (false !== stripos($item['FileLocation'], $locationFilter)) {
53
                if ($this->itemShouldBeIncluded($item)) {
54
                    $this->filteredData[$key] = $item;
55
                }
56
            }
57
        }
58
59
        return $this->formatAsYml();
60
    }
61
62
    public function getYmlForPackage(string $vendorName, string $packageName): string
63
    {
64
        $this->vendorName = $vendorName;
65
        $this->packageName = $packageName;
66
        $this->data = (new ConfigList())->getListOfConfigs();
67
        foreach ($this->data as $key => $item) {
68
            if (strtolower($item['Vendor']) === strtolower($this->vendorName)
69
                &&
70
                strtolower($item['Package']) === strtolower($this->packageName)
71
            ) {
72
                if ($this->itemShouldBeIncluded($item)) {
73
                    $this->filteredData[$key] = $item;
74
                }
75
            }
76
        }
77
78
        return $this->formatAsYml();
79
    }
80
81
    public function getModel()
82
    {
83
        $this->data = (new ConfigList())->getListOfConfigs();
84
        foreach ($this->data as $key => $item) {
85
            if ($this->isModelField($item)) {
86
                $this->filteredData[$key] = $item;
87
            }
88
        }
89
90
        return $this->formatAsYml();
91
    }
92
93
    public function getDataForYmlList(): ArrayData
94
    {
95
        $nestedArray = $this->convertFlatArrayIntoNestedArray($this->filteredData);
96
97
        return $this->convertNestedArrayIntoObjects($nestedArray);
98
        // $this->dataAsObject = new ArrayData(
99
        //     [
100
        //         'Classes' => new ArrayList()
101
        //     ]
102
        // );
103
        // $this->dataAsObject->Classes->push(
104
        //     new ArrayData([
105
        //         'Properties' => $item['Property'],
106
        //         'DefaultValue' => '',
107
        //     ])
108
        //     'FileLocation' => $fileName,
109
        //     'Property' => $property,
110
        //     'Type' => $type,
111
        //     'IsDefault' => $isDefault,
112
        //     'HasDefault' => $hasDefault,
113
        //     'HasValue' => $hasValue,
114
        //     'Default' => $default,
115
        //     'Value' => $value,
116
        // );
117
    }
118
119
    public function getYmlName(): string
120
    {
121
        if ($this->locationFilter) {
122
            $name = strtolower(str_replace('/', '_', $this->locationFilter));
123
        } else {
124
            $name = strtolower($this->vendorName . '_' . $this->packageName);
125
        }
126
127
        return $name . '_config_example';
128
    }
129
130
    protected function formatAsYml(): string
131
    {
132
        return $this->renderWith('Sunnysideup/ConfigManager/View/YmlTemplate');
133
    }
134
135
    protected function convertFlatArrayIntoNestedArray(array $flatArray): array
136
    {
137
        $newArray = [];
138
        $newArray['Classes'] = [];
139
        foreach ($flatArray as $item) {
140
            if (! isset($newArray['Classes'][$item['ClassName']])) {
141
                $newArray['Classes'][$item['ClassName']] = [];
142
                $newArray['Classes'][$item['ClassName']]['ClassName'] = $item['ClassName'];
143
                $newArray['Classes'][$item['ClassName']]['Properties'] = [];
144
            }
145
            if (! isset($newArray['Classes'][$item['ClassName']]['Properties'][$item['Property']])) {
146
                $newArray['Classes'][$item['ClassName']]['Properties'][$item['Property']] = [
147
                    'PropertyName' => $item['Property'],
148
                    'DefaultValue' => $this->bestValue($item['Value']),
149
                ];
150
            }
151
        }
152
153
        return $newArray;
154
    }
155
156
    protected function convertNestedArrayIntoObjects(array $nestedArray): ArrayData
157
    {
158
        $newObject = new ArrayData(
159
            [
160
                'Classes' => new ArrayList(),
161
                'Name' => $this->getYmlName(),
162
            ]
163
        );
164
        foreach ($nestedArray['Classes'] as $properties) {
165
            $itemHolder = new ArrayData(
166
                [
167
                    'ClassName' => $properties['ClassName'],
168
                    'Properties' => new ArrayList(),
169
                ]
170
            );
171
            foreach ($properties['Properties'] as $propertyData) {
172
                $itemHolder->Properties->push(new ArrayData($propertyData));
0 ignored issues
show
Bug introduced by
The method push() does not exist on null. ( Ignorable by Annotation )

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

172
                $itemHolder->Properties->/** @scrutinizer ignore-call */ 
173
                                         push(new ArrayData($propertyData));

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
173
            }
174
            $newObject->Classes->push($itemHolder);
0 ignored issues
show
Bug introduced by
The method push() does not exist on null. ( Ignorable by Annotation )

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

174
            $newObject->Classes->/** @scrutinizer ignore-call */ 
175
                                 push($itemHolder);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
175
        }
176
177
        return $newObject;
178
    }
179
180
    protected function bestValue($mixed)
181
    {
182
        if (is_array($mixed)) {
183
            $val = "\n" . Yaml::dump($mixed);
184
185
            return str_replace("\n", "\n    ", $val);
186
        }
187
        if (is_bool($mixed)) {
188
            if ($mixed) {
189
                return 'true';
190
            }
191
192
            return 'false';
193
        }
194
        if (is_numeric($mixed)) {
195
            if ($mixed) {
196
                return $mixed;
197
            }
198
199
            return 0;
200
        }
201
202
        return Yaml::dump($mixed);
203
    }
204
205
    protected function itemShouldBeIncluded(array $item): bool
206
    {
207
        return ! in_array($item['Property'], $this->Config()->get('excluded_properties'), true);
208
    }
209
210
    protected function isModelField(array $item): bool
211
    {
212
        return in_array($item['Property'], $this->Config()->get('model_fields'), true);
213
    }
214
}
215