Passed
Push — master ( a023d2...6d474d )
by Daniel
06:11
created

AbstractFactory::init()   B

Complexity

Conditions 6
Paths 4

Size

Total Lines 20
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 6

Importance

Changes 0
Metric Value
cc 6
eloc 12
nc 4
nop 3
dl 0
loc 20
ccs 11
cts 11
cp 1
crap 6
rs 8.8571
c 0
b 0
f 0
1
<?php
2
3
namespace Silverback\ApiComponentBundle\Factory\Entity;
4
5
use Doctrine\Common\Persistence\ObjectManager;
6
use Silverback\ApiComponentBundle\Exception\InvalidEntityException;
7
use Silverback\ApiComponentBundle\Exception\InvalidFactoryOptionException;
8
use Symfony\Component\Validator\Validator\ValidatorInterface;
9
10
abstract class AbstractFactory implements FactoryInterface
11
{
12
    public const COMPONENT_CLASSES = [
13
        'className' => null,
14
        'parent' => null
15
    ];
16
17
    /**
18
     * @var ObjectManager
19
     */
20
    protected $manager;
21
22
    /**
23
     * @var null|array
24
     */
25
    protected $ops;
26
27
    /**
28
     * @var ValidatorInterface
29
     */
30
    private $validator;
31
32
    /**
33
     * @param ObjectManager $manager
34
     * @param ValidatorInterface $validator
35
     */
36 58
    public function __construct(
37
        ObjectManager $manager,
38
        ValidatorInterface $validator
39
    ) {
40 58
        $this->manager = $manager;
41 58
        $this->validator = $validator;
42 58
    }
43
44
    /**
45
     * @param $component
46
     * @param array|null $ops
47
     * @param array $ignoreOps
48
     */
49 30
    protected function init($component, ?array $ops = null, ?array $ignoreOps = null): void
50
    {
51 30
        $this->setOptions($ops);
52 30
        foreach ($this->ops as $op=>$value) {
53
            if (
54 29
                null !== $value &&
55
                (
56 25
                    null === $ignoreOps ||
57 29
                    !\in_array($op, $ignoreOps, true)
58
                )
59
            ) {
60 23
                $setter = $this->findSetterMethod($component, $op);
61 23
                if (\is_array($value)) {
62 1
                    $component->$setter(...$value);
63
                } else {
64 29
                    $component->$setter($value);
65
                }
66
            }
67
        }
68 30
        $this->manager->persist($component);
69 30
    }
70
71
    /**
72
     * @param $component
73
     * @param $op
74
     * @return string
75
     */
76 23
    private function findSetterMethod($component, $op): string
77
    {
78 23
        $prefixes = ['set', 'add'];
79 23
        $postfix = ucfirst($op);
80 23
        foreach ($prefixes as $prefix) {
81 23
            $setter = $prefix . $postfix;
82 23
            if (method_exists($component, $setter)) {
83 23
                return $setter;
84
            }
85
        }
86
        throw new \RuntimeException(sprintf('A preconfigured option `%s` has no setter or adder method', $op));
87
    }
88
89
    /**
90
     * @param array|null $ops
91
     * @throws \Silverback\ApiComponentBundle\Exception\InvalidFactoryOptionException
92
     */
93 32
    protected function setOptions(?array $ops): void
94
    {
95 32
        if (!$ops) {
96 6
            $ops = [];
97
        }
98 32
        $this->ops = array_filter(
99 32
            array_merge(static::defaultOps(), $ops),
100 32
            function ($key) {
101 31
                if (!array_key_exists($key, static::defaultOps())) {
102 2
                    throw new InvalidFactoryOptionException(
103 2
                        sprintf('%s is not a valid option for the factory %s', $key, \get_class($this))
104
                    );
105
                }
106 30
                return true;
107 32
            },
108 32
            ARRAY_FILTER_USE_KEY
109
        );
110 30
    }
111
112
    /**
113
     * @param $component
114
     * @return bool
115
     * @throws \Silverback\ApiComponentBundle\Exception\InvalidEntityException
116
     */
117 27
    protected function validate($component): bool
118
    {
119 27
        $errors = $this->validator->validate($component);
120 27
        if (\count($errors)) {
121
            throw new InvalidEntityException($errors);
122
        }
123 27
        return true;
124
    }
125
126
    /**
127
     * @return array
128
     */
129 3
    protected static function defaultOps(): array
130
    {
131 3
        return [];
132
    }
133
134
    /**
135
     * @param array|null $ops
136
     */
137
    abstract public function create(?array $ops = null);
138
}
139