ObjectHelper::findClassFromConfig()   B
last analyzed

Complexity

Conditions 6
Paths 8

Size

Total Lines 33
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 42

Importance

Changes 0
Metric Value
dl 0
loc 33
ccs 0
cts 25
cp 0
rs 8.439
c 0
b 0
f 0
cc 6
eloc 18
nc 8
nop 2
crap 42
1
<?php
2
3
/**
4
 * @copyright  Copyright (c) Flipbox Digital Limited
5
 * @license    https://github.com/flipbox/spark/blob/master/LICENSE
6
 * @link       https://github.com/flipbox/spark
7
 */
8
9
namespace flipbox\spark\helpers;
10
11
use craft\helpers\Json as JsonHelper;
12
use yii\base\InvalidConfigException;
13
use yii\base\Object as BaseObject;
14
15
/**
16
 * @author Flipbox Factory <[email protected]>
17
 * @since 1.0.0
18
 */
19
class ObjectHelper
20
{
21
22
    /**
23
     * Configures an object with the initial property values.
24
     *
25
     * @param BaseObject $object
26
     * @param array $properties
27
     * @return BaseObject
28
     */
29
    public static function populate(BaseObject $object, $properties = []): BaseObject
30
    {
31
32
        // Set properties
33
        foreach ($properties as $name => $value) {
34
            if ($object->canSetProperty($name)) {
35
                $object->$name = $value;
36
            }
37
        }
38
39
        return $object;
40
    }
41
42
    /**
43
     * Create a new object
44
     *
45
     * @param $config
46
     * @param string|null $instanceOf
47
     * @throws InvalidConfigException
48
     * @return BaseObject
49
     */
50
    public static function create($config, string $instanceOf = null): BaseObject
51
    {
52
53
        // Get class from config
54
        $class = static::checkConfig($config, $instanceOf);
55
56
        // New object
57
        $object = new $class();
58
59
        // Populate
60
        if ($config) {
61
            static::populate($object, $config);
62
        }
63
64
        return $object;
65
    }
66
67
    /**
68
     * Checks the config for a valid class
69
     *
70
     * @param $config
71
     * @param string|null $instanceOf
72
     * @param bool $removeClass
73
     * @throws InvalidConfigException
74
     * @return string
75
     */
76
    public static function checkConfig(&$config, string $instanceOf = null, bool $removeClass = true): string
77
    {
78
79
        // Get class from config
80
        $class = static::getClassFromConfig($config, $removeClass);
81
82
        // Make sure we have a valid class
83
        if ($instanceOf && !is_subclass_of($class, $instanceOf)) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $instanceOf of type null|string is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
Bug introduced by
Due to PHP Bug #53727, is_subclass_of might return inconsistent results on some PHP versions if $instanceOf can be an interface. If so, you could instead use ReflectionClass::implementsInterface.
Loading history...
84
            throw new InvalidConfigException(
85
                sprintf(
86
                    "The class '%s' must be an instance of '%s'",
87
                    (string)$class,
88
                    (string)$instanceOf
89
                )
90
            );
91
        }
92
93
        return $class;
94
    }
95
96
    /**
97
     * Get a class from a config
98
     *
99
     * @param $config
100
     * @param bool $removeClass
101
     * @throws InvalidConfigException
102
     * @return string
103
     */
104
    public static function getClassFromConfig(&$config, bool $removeClass = false): string
105
    {
106
107
        // Find class
108
        $class = static::findClassFromConfig($config, $removeClass);
109
110
        if (empty($class)) {
111
            throw new InvalidConfigException(
112
                sprintf(
113
                    "The configuration must specify a 'class' property: '%s'",
114
                    JsonHelper::encode($config)
115
                )
116
            );
117
        }
118
119
        return $class;
120
    }
121
122
    /**
123
     * Find a class from a config
124
     *
125
     * @param $config
126
     * @param bool $removeClass
127
     * @return null|string
128
     */
129
    public static function findClassFromConfig(&$config, bool $removeClass = false)
130
    {
131
132
        // Normalize the config
133
        if (is_string($config)) {
134
            // Set as class
135
            $class = $config;
136
137
            // Clear class from config
138
            $config = '';
139
        } elseif (is_object($config)) {
140
            return get_class($config);
141
        } else {
142
            // Force Array
143
            if (!is_array($config)) {
144
                $config = ArrayHelper::toArray($config, [], false);
145
            }
146
147
            if ($removeClass) {
148
                if (!$class = ArrayHelper::remove($config, 'class')) {
149
                    $class = ArrayHelper::remove($config, 'type');
150
                }
151
            } else {
152
                $class = ArrayHelper::getValue(
153
                    $config,
154
                    'class',
155
                    ArrayHelper::getValue($config, 'type')
156
                );
157
            }
158
        }
159
160
        return $class;
161
    }
162
}
163