Passed
Branch master (3793ef)
by Nicolaas
03:26 queued 01:31
created

ConfigList::getDefaultLists()   B

Complexity

Conditions 6
Paths 5

Size

Total Lines 31
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 6
eloc 22
c 1
b 0
f 0
nc 5
nop 2
dl 0
loc 31
rs 8.9457
1
<?php
2
3
namespace Sunnysideup\ConfigManager\Api;
4
5
use ReflectionClass;
6
use SilverStripe\Control\Director;
7
use SilverStripe\Core\ClassInfo;
8
use SilverStripe\Core\Config\Config;
9
use SilverStripe\Core\Config\Configurable;
10
use SilverStripe\Core\Extensible;
11
use SilverStripe\Core\Injector\Injectable;
12
13
class ConfigList
14
{
15
    use Extensible;
16
    use Injectable;
17
    use Configurable;
18
19
    private static $do_not_show = [
1 ignored issue
show
introduced by
The private property $do_not_show is not used, and could be removed.
Loading history...
20
        'extra_methods',
21
        'built_in_methods',
22
    ];
23
24
    // protected $locationIncludes = [];
25
    //
26
    // protected $classNameIncludes = [];
27
    //
28
    // public function setLocationIncludes($a)
29
    // {
30
    //     $this->locationIncludes = $a;
31
    //
32
    //     return $this;
33
    // }
34
    //
35
    // public function setClassNameIncludes($a)
36
    // {
37
    //     $this->classNameIncludes = $a;
38
    //
39
    //     return $this;
40
    // }
41
42
    /**
43
     * @return array
44
     */
45
    public function getListOfConfigs(): array
46
    {
47
        $resultArray = [];
48
49
        $doNotShow = $this->Config()->get('do_not_show');
50
51
        $config = Config::inst();
52
        $alsoSet = $config->getAll();
53
        $base = Director::baseFolder();
54
55
        $classes = $this->configurableClasses();
56
        foreach ($classes as $class) {
57
            $reflector = new ReflectionClass($class);
58
            $fileName = $reflector->getFileName();
59
            $fileName = str_replace($base, '', $fileName);
60
61
            //lists
62
            $staticListDelta = $this->getDeltas($config, $class);
0 ignored issues
show
Bug introduced by
$config of type SilverStripe\Config\Coll...nfigCollectionInterface is incompatible with the type SilverStripe\Core\Config\Config expected by parameter $config of Sunnysideup\ConfigManage...ConfigList::getDeltas(). ( Ignorable by Annotation )

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

62
            $staticListDelta = $this->getDeltas(/** @scrutinizer ignore-type */ $config, $class);
Loading history...
63
            $staticListDynamic = array_keys($alsoSet[strtolower($class)]);
64
            $defaultLists = $this->getDefaultLists($reflector, $doNotShow);
65
            $originalValues = $defaultLists['OriginalValues'];
66
67
            $lists = [
68
                //do first so that they will always show up
69
                'runtime' => $staticListDelta,
70
                'system' => $defaultLists['Caching'],
71
                'caching' => $defaultLists['System'],
72
                'property' => $defaultLists['Property'],
73
                //needs to be last so that only dynamic ones that are
74
                //not set as property are included
75
                'dynamic' => $staticListDynamic,
76
            ];
77
78
            foreach ($lists as $type => $list) {
79
                foreach ($list as $property) {
80
                    $key = str_replace('/', '-', $fileName . '-' . $property);
81
                    if (! isset($resultArray[$key])) {
82
                        $value = $config->get($class, $property, Config::UNINHERITED);
83
                        $hasValue = $value ? true : false;
84
                        $originalValue = isset($originalValues[$property]) ? $originalValues[$property] : '';
85
                        if (is_object($value)) {
86
                            $value = 'object';
87
                        }
88
                        $isDefault = true;
89
                        $default = '';
90
                        if ($originalValue && $originalValue !== $value) {
91
                            $isDefault = false;
92
                            if ($value && $originalValue) {
93
                                $default = $originalValue;
94
                            }
95
                        }
96
                        $hasDefault = $originalValue ? true : false;
97
                        $resultArray[$key] = array_merge(
98
                            $this->getClassIntel($class),
99
                            [
100
                                'FileLocation' => $fileName,
101
                                'Property' => $property,
102
                                'Type' => $type,
103
                                'IsDefault' => $isDefault,
104
                                'HasDefault' => $hasDefault,
105
                                'HasValue' => $hasValue,
106
                                'Default' => $default,
107
                                'Value' => $value,
108
                            ]
109
                        );
110
                    }
111
                }
112
            }
113
        }
114
115
        return $resultArray;
116
    }
117
118
    /**
119
     * info about class
120
     * @param  string $reflector
121
     *
122
     * @return array
123
     */
124
    protected function getDefaultLists($reflector, $doNotShow): array
125
    {
126
        //vars
127
        $staticListSystem = [];
128
        $staticListCaching = [];
129
        $staticListProperty = [];
130
        $originalValues = [];
131
        //start loop
132
        $statics = $reflector->getStaticProperties();
133
        foreach (array_keys($statics) as $property) {
134
            $propertyObject = $reflector->getProperty($property);
135
            if ($propertyObject->isPrivate()) {
136
                $propertyObject->setAccessible(true);
137
                $originalValues[$property] = $propertyObject->getValue($reflector);
138
139
                if (in_array($property, $doNotShow, true)) {
140
                    $staticListSystem[$property] = $property;
141
                } elseif (substr($property, 0, 1) === '_' ||
142
                    strpos($property, 'cache') !== false
143
                ) {
144
                    $staticListCaching[$property] = $property;
145
                } else {
146
                    $staticListProperty[$property] = $property;
147
                }
148
            }
149
        }
150
        return [
151
            'System' => $staticListSystem,
152
            'Caching' => $staticListCaching,
153
            'Property' => $staticListProperty,
154
            'OriginalValues' => $originalValues,
155
        ];
156
    }
157
158
    /**
159
     * info about class
160
     * @param  string $class
161
     *
162
     * @return array
163
     */
164
    protected function getClassIntel($class): array
165
    {
166
        $vendor = 'n/a';
167
        $package = 'n/a';
168
        $shorterClassname = $class;
169
        $classNameArray = explode('\\', $class);
170
        $shortClassName = ClassInfo::shortName($class);
171
        $ancestry = ClassInfo::ancestry($class);
172
        $childClasses = ClassInfo::subclassesFor($class, false);
173
        if (count($classNameArray) > 1) {
174
            $vendor = $classNameArray[0];
175
            $package = $classNameArray[1];
176
            array_shift($classNameArray);
177
            array_shift($classNameArray);
178
            $shorterClassname = implode(' / ', $classNameArray);
179
        }
180
181
        return [
182
            'Vendor' => $vendor,
183
            'Package' => $package,
184
            'ClassName' => $class,
185
            'ShorterClassName' => $shorterClassname,
186
            'ShortClassName' => $shortClassName,
187
            'ParentClasses' => $ancestry,
188
            'ChildClasses' => $childClasses,
189
        ];
190
    }
191
192
    /**
193
     * get values set at run time (deltas / changed ones)
194
     *
195
     * @param  Config $config
196
     * @param  string $className
197
     * @return array
198
     */
199
    protected function getDeltas($config, $className): array
200
    {
201
        $deltaList = [];
202
        $deltas = $config->getDeltas($className);
0 ignored issues
show
Bug introduced by
The method getDeltas() does not exist on SilverStripe\Core\Config\Config. ( Ignorable by Annotation )

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

202
        /** @scrutinizer ignore-call */ 
203
        $deltas = $config->getDeltas($className);

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...
203
        if (count($deltas)) {
204
            foreach ($deltas as $deltaInners) {
205
                if (isset($deltaInners['config'])) {
206
                    $deltaList = array_merge(
207
                        $deltaList,
208
                        array_keys($deltaInners['config'])
209
                    );
210
                }
211
            }
212
        }
213
214
        return $deltaList;
215
    }
216
217
    /**
218
     * @return array
219
     */
220
    protected function configurableClasses(): array
221
    {
222
        $definedClasses = ClassInfo::allClasses();
223
224
        return array_filter(
225
            $definedClasses,
226
            function ($className) {
227
                if (class_exists($className)) {
228
                    $autoload = true;
229
                    $traits = [];
230
                    $class = $className;
231
                    // Get traits of all parent classes
232
                    do {
233
                        $traits = array_merge(class_uses($class, $autoload), $traits);
234
                        $class = get_parent_class($class);
235
                    } while ($class);
236
237
                    // Get traits of all parent traits
238
                    $traitsToSearch = $traits;
239
                    while (! empty($traitsToSearch)) {
240
                        $newTraits = class_uses(array_pop($traitsToSearch), $autoload);
241
                        $traits = array_merge($newTraits, $traits);
242
                        $traitsToSearch = array_merge($newTraits, $traitsToSearch);
243
                    }
244
245
                    foreach (array_keys($traits) as $trait) {
246
                        $traits = array_merge(class_uses($trait, $autoload), $traits);
247
                    }
248
                    return isset($traits[Configurable::class]);
249
                }
250
            }
251
        );
252
    }
253
}
254