Passed
Push — master ( d705ca...076418 )
by Nicolaas
01:48
created

ConfigList::getClassIntel()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 25
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 21
c 0
b 0
f 0
nc 2
nop 1
dl 0
loc 25
rs 9.584
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
20
    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...
21
        'extra_methods',
22
        'built_in_methods'
23
    ];
24
25
    // protected $locationIncludes = [];
26
    //
27
    // protected $classNameIncludes = [];
28
    //
29
    // public function setLocationIncludes($a)
30
    // {
31
    //     $this->locationIncludes = $a;
32
    //
33
    //     return $this;
34
    // }
35
    //
36
    // public function setClassNameIncludes($a)
37
    // {
38
    //     $this->classNameIncludes = $a;
39
    //
40
    //     return $this;
41
    // }
42
43
    /**
44
     * @return array
45
     */
46
    public function getListOfConfigs(): array
47
    {
48
        $resultArray = [];
49
50
        $doNotShow = $this->Config()->get('do_not_show');
51
52
        $config = Config::inst();
53
        $alsoSet = $config->getAll();
54
        $base = Director::baseFolder();
55
56
        $classes = $this->configurableClasses();
57
        foreach ($classes as $class) {
58
            $reflector = new ReflectionClass($class);
59
            $fileName = $reflector->getFileName();
60
            $fileName = str_replace($base, '', $fileName);
61
            $statics = $reflector->getStaticProperties();
62
63
            //lists
64
            $staticListSystem = [];
65
            $staticListProperty = [];
66
            $staticListCaching = [];
67
            $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

67
            $staticListDelta = $this->getDeltas(/** @scrutinizer ignore-type */ $config, $class);
Loading history...
68
            $staticListDynamic = array_keys($alsoSet[strtolower($class)]);
69
            unset($originalValues);
70
            $originalValues = [];
71
            foreach ($statics as $property => $details) {
72
                $propertyObject = $reflector->getProperty($property);
73
                if($propertyObject->isPrivate()) {
74
                    $propertyObject->setAccessible(true);
75
                    $originalValues[$property] = $propertyObject->getValue($reflector);
76
77
                    if (in_array($property, $doNotShow, true)) {
78
                        $staticListSystem[$property] = $property;
79
                    } elseif (substr($property, 0, 1) === '_' ||
80
                        strpos($property, 'cache') !== false
81
                    ) {
82
                        $staticListCaching[$property] = $property;
83
                    } else {
84
                        $staticListProperty[$property] = $property;
85
                    }
86
                }
87
            }
88
            $lists = [
89
                'runtime' => $staticListDelta,
90
                'caching' => $staticListCaching,
91
                'system' => $staticListSystem,
92
                'property' => $staticListProperty,
93
                'dynamic' => $staticListDynamic,
94
            ];
95
96
            foreach ($lists as $type => $list) {
97
                foreach ($list as $property) {
98
                    $key = str_replace('/', '-', $fileName . '-' . $property);
99
                    if (! isset($resultArray[$key])) {
100
                        $value = $config->get($class, $property, Config::UNINHERITED);
101
                        $hasValue = $value ? true : false;
102
                        $originalValue = isset($originalValues[$property]) ? $originalValues[$property] : '';
103
                        if (is_object($value)) {
104
                            $value = 'object';
105
                        }
106
                        $isDefault = true;
107
                        $default = '';
108
                        if ($originalValue && $originalValue !== $value) {
109
                            $isDefault = false;
110
                            if ($value && $originalValue) {
111
                                $default = $originalValue;
112
                            }
113
                        }
114
                        $hasDefault = $originalValue ? true : false;
115
                        $resultArray[$key] = array_merge(
116
                            $this->getClassIntel($class),
117
                            [
118
                                'FileLocation' => $fileName,
119
                                'Property' => $property,
120
                                'Type' => $type,
121
                                'IsDefault' => $isDefault,
122
                                'HasDefault' => $hasDefault,
123
                                'HasValue' => $hasValue,
124
                                'Default' => $default,
125
                                'Value' => $value,
126
                            ]
127
                        );
128
                    }
129
                }
130
            }
131
        }
132
133
        return $resultArray;
134
    }
135
136
    /**
137
     * info about class
138
     * @param  string $class
139
     *
140
     * @return array
141
     */
142
    protected function getClassIntel($class): array
143
    {
144
        $vendor = 'n/a';
145
        $package = 'n/a';
146
        $shorterClassname = $class;
147
        $classNameArray = explode('\\', $class);
148
        $shortClassName = ClassInfo::shortName($class);
149
        $ancestry = ClassInfo::ancestry($class);
150
        $childClasses = ClassInfo::subclassesFor($class, false);
151
        if (count($classNameArray) > 1) {
152
            $vendor = $classNameArray[0];
153
            $package = $classNameArray[1];
154
            array_shift($classNameArray);
155
            array_shift($classNameArray);
156
            $shorterClassname = implode(' / ', $classNameArray);
157
        }
158
159
        return [
160
            'Vendor' => $vendor,
161
            'Package' => $package,
162
            'ClassName' => $class,
163
            'ShorterClassName' => $shorterClassname,
164
            'ShortClassName' => $shortClassName,
165
            'ParentClasses' => $ancestry,
166
            'ChildClasses' => $childClasses,
167
        ];
168
    }
169
170
    /**
171
     * get values set at run time (deltas / changed ones)
172
     *
173
     * @param  Config $config
174
     * @param  string $className
175
     * @return array
176
     */
177
    protected function getDeltas($config, $className): array
178
    {
179
        $deltaList = [];
180
        $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

180
        /** @scrutinizer ignore-call */ 
181
        $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...
181
        if (count($deltas)) {
182
            foreach ($deltas as $deltaInners) {
183
                if (isset($deltaInners['config'])) {
184
                    $deltaList = array_merge(
185
                        $deltaList,
186
                        array_keys($deltaInners['config'])
187
                    );
188
                }
189
            }
190
        }
191
192
        return $deltaList;
193
    }
194
195
    /**
196
     *
197
     * @return array
198
     */
199
    protected function configurableClasses(): array
200
    {
201
        $definedClasses = ClassInfo::allClasses();
202
203
        return array_filter(
204
            $definedClasses,
205
            function ($className) {
206
                if (class_exists($className)) {
207
                    $autoload = true;
208
                    $traits = [];
209
                    $class = $className;
210
                    // Get traits of all parent classes
211
                    do {
212
                        $traits = array_merge(class_uses($class, $autoload), $traits);
213
                        $class = get_parent_class($class);
214
                    } while ($class);
215
216
                    // Get traits of all parent traits
217
                    $traitsToSearch = $traits;
218
                    while (! empty($traitsToSearch)) {
219
                        $newTraits = class_uses(array_pop($traitsToSearch), $autoload);
220
                        $traits = array_merge($newTraits, $traits);
221
                        $traitsToSearch = array_merge($newTraits, $traitsToSearch);
222
                    }
223
224
                    foreach (array_keys($traits) as $trait) {
225
                        $traits = array_merge(class_uses($trait, $autoload), $traits);
226
                    }
227
                    return isset($traits[Configurable::class]);
228
                }
229
            }
230
        );
231
    }
232
}
233