Passed
Push — develop ( 96281a...e6f82b )
by Daniel
05:53 queued 26s
created

AbstractFactory   A

Complexity

Total Complexity 16

Size/Duplication

Total Lines 127
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
eloc 40
dl 0
loc 127
ccs 0
cts 44
cp 0
rs 10
c 0
b 0
f 0
wmc 16

7 Methods

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