Completed
Push — master ( cbb1d6...c695eb )
by Juuso
03:36
created

validateConfiguredInstance()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 20
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 3

Importance

Changes 0
Metric Value
dl 0
loc 20
ccs 9
cts 9
cp 1
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 11
nc 3
nop 2
crap 3
1
<?php
2
3
namespace leinonen\Yii2Monolog\Factories;
4
5
use Monolog\Formatter\FormatterInterface;
6
use Monolog\Handler\HandlerInterface;
7
use Yii;
8
use yii\base\InvalidConfigException;
9
use leinonen\Yii2Monolog\CreationStrategies\StrategyResolver;
10
use leinonen\Yii2Monolog\CreationStrategies\CreationStrategyInterface;
11
12
class GenericStrategyBasedFactory
13
{
14
    /**
15
     * @var StrategyResolver
16
     */
17
    private $strategyResolver;
18
19
    /**
20
     * Initiates a new AbstractStrategyBasedFactory.
21
     *
22
     * @param StrategyResolver $strategyResolver
23
     */
24 7
    public function __construct(StrategyResolver $strategyResolver)
25
    {
26 7
        $this->strategyResolver = $strategyResolver;
27 7
    }
28
29
    /**
30
     * Makes the given class with config utilizing the resolved strategy based on class.
31
     *
32
     * @param string $className
33
     * @param array $config
34
     *
35
     * @see StrategyResolver::resolve()
36
     *
37
     * @return mixed
38
     * @throws InvalidConfigException
39
     */
40 7
    public function makeWithStrategy(
41
        string $className,
42
        array $config = []
43
    ) {
44 7
        $strategy = $this->strategyResolver->resolve($className);
45 7
        $this->validateConfigParameters($strategy, $className, $config);
46
47 6
        $instance = Yii::$container->get($className, $strategy->getConstructorParameters($config));
48 6
        $configure = $strategy->getConfigurationCallable($config);
49
50 6
        $configuredInstance = $configure($instance, $config);
51 6
        $this->validateConfiguredInstance($configuredInstance, $className);
52
53 2
        return $configuredInstance;
54
    }
55
56
    /**
57
     * Validates the given config against the given strategy.
58
     *
59
     * @param CreationStrategyInterface $strategy
60
     * @param string $className
61
     * @param array $config
62
     *
63
     * @throws InvalidConfigException
64
     */
65 7
    private function validateConfigParameters(
66
        CreationStrategyInterface $strategy,
67
        string $className,
68
        array $config
69
    ) {
70 7
        $requiredParameters = $strategy->getRequiredParameters();
71 7
        $givenParameters = \array_keys($config);
72
73 7
        foreach ($requiredParameters as $requiredParameter) {
74 3
            if (! \in_array($requiredParameter, $givenParameters, true)) {
75 1
                throw new InvalidConfigException(
76 3
                    "The parameter '{$requiredParameter}' is required for {$className}"
77
                );
78
            }
79
        }
80 6
    }
81
82
    /**
83
     * @param HandlerInterface|FormatterInterface|callable $configuredInstance
84
     * @param string $className
85
     *
86
     * @throws InvalidConfigException
87
     */
88 6
    private function validateConfiguredInstance($configuredInstance, string $className)
89
    {
90 6
        if (! \is_object($configuredInstance)) {
91 3
           throw new InvalidConfigException(
92
               \sprintf(
93 3
                   'The return value of the configure callable must be an instance of %s got %s',
94
                   $className,
95
                   \gettype($configuredInstance)
96
               )
97
           );
98
        }
99
100 3
        $instanceClassName = (new \ReflectionClass($configuredInstance))->name;
101
102 3
        if ($instanceClassName !== $className) {
103 1
            throw new InvalidConfigException(
104 1
                "The return value of the configure callable must be an instance of {$className} got {$instanceClassName}"
105
            );
106
        }
107 2
    }
108
}
109