EntityContext::getMetadata()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 1
c 1
b 0
f 0
dl 0
loc 3
rs 10
cc 1
nc 1
nop 1
1
<?php
2
3
namespace Knp\FriendlyContexts\Context;
4
5
use Behat\Gherkin\Node\TableNode;
6
use Doctrine\ORM\EntityManager;
7
use Doctrine\ORM\Tools\SchemaTool;
8
9
class EntityContext extends Context
10
{
11
    /**
12
     * @Given /^the following ([\w ]+):?$/
13
     */
14
    public function theFollowing($name, TableNode $table)
15
    {
16
        $entityName = $this->resolveEntity($name)->getName();
17
18
        $rows = $table->getRows();
19
        $headers = array_shift($rows);
20
21
        foreach ($rows as $row) {
22
            $values     = array_combine($headers, $row);
23
            $entity     = new $entityName;
24
            $reflection = new \ReflectionClass($entity);
25
26
            do {
27
                $this
28
                    ->getRecordBag()
29
                    ->getCollection($reflection->getName())
30
                    ->attach($entity, $values)
31
                ;
32
                $reflection = $reflection->getParentClass();
33
            } while (false !== $reflection);
34
35
            $this
36
                ->getEntityHydrator()
37
                ->hydrate($this->getEntityManager(), $entity, $values)
38
                ->completeRequired($this->getEntityManager(), $entity)
39
            ;
40
41
            $this->getEntityManager()->persist($entity);
42
        }
43
44
        $this->getEntityManager()->flush();
45
    }
46
47
    /**
48
     * @Given /^there (?:is|are) (\d+) ((?!\w* like)\w*)$/
49
     */
50
    public function thereIs($nbr, $name)
51
    {
52
        $entityName = $this->resolveEntity($name)->getName();
53
54
        for ($i = 0; $i < $nbr; $i++) {
55
            $entity = new $entityName;
56
            $this
57
                ->getRecordBag()
58
                ->getCollection($entityName)
59
                ->attach($entity)
60
            ;
61
            $this
62
                ->getEntityHydrator()
63
                ->completeRequired($this->getEntityManager(), $entity)
64
            ;
65
66
            $this->getEntityManager()->persist($entity);
67
        }
68
69
        $this->getEntityManager()->flush();
70
    }
71
72
    /**
73
     * @Given /^there (?:is|are) (\d+) (.*) like:?$/
74
     */
75
    public function thereIsLikeFollowing($nbr, $name, TableNode $table)
76
    {
77
        $entityName = $this->resolveEntity($name)->getName();
78
79
        $rows = $table->getRows();
80
        $headers = array_shift($rows);
81
82
        for ($i = 0; $i < $nbr; $i++) {
83
            $row = $rows[$i % count($rows)];
84
            $values = array_combine($headers, $row);
85
            $entity = new $entityName;
86
            $this
87
                ->getRecordBag()
88
                ->getCollection($entityName)
89
                ->attach($entity, $values)
90
            ;
91
            $this
92
                ->getEntityHydrator()
93
                ->hydrate($this->getEntityManager(), $entity, $values)
94
                ->completeRequired($this->getEntityManager(), $entity)
95
            ;
96
97
            $this->getEntityManager()->persist($entity);
98
        }
99
100
        $this->getEntityManager()->flush();
101
    }
102
103
    /**
104
     * @Given /^(\w+) (.+) should have been (created|deleted)$/
105
     */
106
    public function entitiesShouldHaveBeen($expected, $entity, $state)
107
    {
108
        $expected = (int) $expected;
109
110
        $entityName = $this->resolveEntity($entity)->getName();
111
        $collection = $this
112
            ->getRecordBag()
113
            ->getCollection($entityName)
114
        ;
115
116
        $records = array_map(function ($e) { return $e->getEntity(); }, $collection->all());
117
        $entities = $this
118
            ->getEntityManager()
119
            ->getRepository($entityName)
120
            ->createQueryBuilder('o')
121
            ->resetDQLParts()
122
            ->select('o')
123
            ->from($entityName, ' o')
124
            ->getQuery()
125
            ->getResult()
126
        ;
127
128
        if ($state === 'created') {
129
            $diff = $this->compareArray($entities, $records);
130
            foreach ($diff as $e) {
131
                $collection->attach($e);
132
            }
133
        } else {
134
            $diff = $this->compareArray($records, $entities);
135
        }
136
        $real = count($diff);
137
138
        $this
139
            ->getAsserter()
140
            ->assertEquals(
141
                $real,
142
                $expected,
143
                sprintf('%s %s should have been %s, %s actually', $expected, $entity, $state, $real)
144
            )
145
        ;
146
    }
147
148
    /**
149
     * @Then /^should be (\d+) (.*) like:?$/
150
     */
151
    public function existLikeFollowing($nbr, $name, TableNode $table)
152
    {
153
        $entityName = $this->resolveEntity($name)->getName();
154
155
        $rows = $table->getRows();
156
        $headers = array_shift($rows);
157
158
        for ($i = 0; $i < $nbr; $i++) {
159
            $row = $rows[$i % count($rows)];
160
161
            $values = array_map(array($this, 'clean'), array_combine($headers, $row));
0 ignored issues
show
Bug introduced by
It seems like array_combine($headers, $row) can also be of type false; however, parameter $arr1 of array_map() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

161
            $values = array_map(array($this, 'clean'), /** @scrutinizer ignore-type */ array_combine($headers, $row));
Loading history...
162
            $object = $this->getEntityManager()
163
                ->getRepository($entityName)
164
                ->findOneBy($values);
165
166
            if (is_null($object)) {
167
                throw new \Exception(sprintf("There is no object for the following criteria: %s", json_encode($values)));
168
            }
169
            $this->getEntityManager()->refresh($object);
170
        }
171
    }
172
173
    /**
174
     * @BeforeScenario
175
     */
176
    public function beforeScenario($event)
177
    {
178
        $this->storeTags($event);
179
180
        if ($this->hasTags([ 'reset-schema', '~not-reset-schema' ])) {
181
            foreach ($this->getEntityManagers() as $entityManager) {
182
                $metadata = $this->getMetadata($entityManager);
183
184
                if (!empty($metadata)) {
185
                    $tool = new SchemaTool($entityManager);
186
                    $tool->dropSchema($metadata);
187
                    $tool->createSchema($metadata);
188
                }
189
            }
190
        }
191
192
    }
193
194
    /**
195
     * @AfterScenario
196
     */
197
    public function afterScenario($event)
0 ignored issues
show
Unused Code introduced by
The parameter $event is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

197
    public function afterScenario(/** @scrutinizer ignore-unused */ $event)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
198
    {
199
        $this->getRecordBag()->clear();
200
        $this->getUniqueCache()->clear();
201
        $this->getEntityManager()->clear();
202
    }
203
204
    protected function compareArray(array $a1, array $a2)
205
    {
206
        $diff = [];
207
        foreach ($a1 as $e) {
208
            if (!in_array($e, $a2)) {
209
                $diff[] = $e;
210
            }
211
        }
212
213
        return $diff;
214
    }
215
216
    protected function getMetadata(EntityManager $entityManager)
217
    {
218
        return $entityManager->getMetadataFactory()->getAllMetadata();
219
    }
220
221
    protected function getEntityManagers()
222
    {
223
        return $this->get('doctrine')->getManagers();
224
    }
225
226
    protected function getConnections()
227
    {
228
        return $this->get('doctrine')->getConnections();
229
    }
230
231
    protected function getDefaultOptions()
232
    {
233
        return [
234
            'Entities' => [''],
235
        ];
236
    }
237
238
    /**
239
     * @param mixed $value
240
     *
241
     * @return mixed
242
     */
243
    protected function clean($value)
244
    {
245
        return trim($value) === '' ? null : $value;
246
    }
247
}
248