Completed
Pull Request — master (#270)
by Luc
06:03
created

DBALRepository::getPlaceOfEvent()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 1
1
<?php
2
/**
3
 * @file
4
 */
5
6
namespace CultuurNet\UDB3\Event\ReadModel\Relations\Doctrine;
7
8
use CultuurNet\UDB3\Event\ReadModel\Relations\RepositoryInterface;
9
use Doctrine\DBAL\Connection;
10
use Doctrine\DBAL\Schema\Schema;
11
12
class DBALRepository implements RepositoryInterface
13
{
14
    protected $tableName = 'event_relations';
15
16
    /**
17
     * @var Connection
18
     */
19
    protected $connection;
20
21
    /**
22
     * @param Connection $connection
23
     */
24
    public function __construct(Connection $connection)
25
    {
26
        $this->connection = $connection;
27
    }
28
29
    public function storeRelations($eventId, $placeId, $organizerId)
30
    {
31
        $this->connection->beginTransaction();
32
33
        $insert = $this->prepareInsertStatement();
34
        $insert->bindValue('event', $eventId);
35
        $insert->bindValue('place', $placeId);
36
        $insert->bindValue('organizer', $organizerId);
37
        $insert->execute();
38
39
        $this->connection->commit();
40
    }
41
42
    public function removeOrganizer($eventId)
43
    {
44
        $transaction = function ($connection) use ($eventId) {
45
            if ($this->eventHasRelations($connection, $eventId)) {
46
                $this->updateEventRelation($connection, $eventId, 'organizer', null);
47
            }
48
        };
49
50
        $this->connection->transactional($transaction);
51
    }
52
53
    public function storeOrganizer($eventId, $organizerId)
54
    {
55
        $this->storeRelation($eventId, 'organizer', $organizerId);
56
    }
57
58
    /**
59
     * @param string $eventId
60
     * @param string $relationType either 'place' or 'organizer'
61
     * @param string $itemId
62
     */
63
    public function storeRelation($eventId, $relationType, $itemId)
64
    {
65
        $transaction = function ($connection) use ($eventId, $relationType, $itemId) {
66
            if ($this->eventHasRelations($connection, $eventId)) {
67
                $this->updateEventRelation($connection, $eventId, $relationType, $itemId);
68
            } else {
69
                $this->createEventRelation($connection, $eventId, $relationType, $itemId);
70
            }
71
        };
72
73
        $this->connection->transactional($transaction);
74
    }
75
76
    /**
77
     * @param Connection $connection
78
     * @param string $eventId
79
     * @param string $relationType
80
     * @param string $itemId
81
     */
82
    private function createEventRelation(
83
        Connection $connection,
84
        $eventId,
85
        $relationType,
86
        $itemId
87
    ) {
88
        $q = $connection
89
            ->createQueryBuilder()
90
            ->insert($this->tableName)
91
            ->values([
92
                'event' => ':event_id',
93
                $relationType => ':item_id'
94
            ])
95
            ->setParameter('event_id', $eventId)
96
            ->setParameter('item_id', $itemId);
97
98
        $q->execute();
99
    }
100
101
    /**
102
     * @param Connection $connection
103
     * @param string $eventId
104
     * @param string $relationType
105
     * @param string $itemId
106
     */
107
    private function updateEventRelation(
108
        Connection $connection,
109
        $eventId,
110
        $relationType,
111
        $itemId
112
    ) {
113
        $q = $connection
114
            ->createQueryBuilder()
115
            ->update($this->tableName)
116
            ->where('event = :event_id')
117
            ->set($relationType, ':item_id')
118
            ->setParameter('event_id', $eventId)
119
            ->setParameter('item_id', $itemId);
120
121
        $q->execute();
122
    }
123
124
    /**
125
     * @param Connection $connection
126
     * @param string $id
127
     * @return bool
128
     */
129
    private function eventHasRelations(
130
        Connection $connection,
131
        $id
132
    ) {
133
        $q = $connection->createQueryBuilder();
134
135
        $q->select('1')
136
            ->from($this->tableName, 'relation')
137
            ->where('relation.event = :event_id')
138
            ->setParameter('event_id', $id);
139
140
        $result = $q->execute();
141
        $relations = $result->fetchAll();
142
143
        return count($relations) > 0;
144
    }
145
146
    private function prepareInsertStatement()
147
    {
148
        $table = $this->connection->quoteIdentifier($this->tableName);
149
        return $this->connection->prepare(
150
            "INSERT INTO {$table} SET
151
              event = :event,
152
              place = :place,
153
              organizer = :organizer
154
            ON DUPLICATE KEY UPDATE
155
              place = :place,
156
              organizer=:organizer"
157
        );
158
    }
159
160 View Code Duplication
    public function getEventsLocatedAtPlace($placeId)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
161
    {
162
        $q = $this->connection->createQueryBuilder();
163
        $q->select('event')
164
          ->from($this->tableName)
165
          ->where('place = ?')
166
          ->setParameter(0, $placeId);
167
168
        $results = $q->execute();
169
170
        $events = array();
171
        while ($id = $results->fetchColumn(0)) {
172
            $events[] = $id;
173
        }
174
175
        return $events;
176
    }
177
178 View Code Duplication
    public function getEventsOrganizedByOrganizer($organizerId)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
179
    {
180
        $q = $this->connection->createQueryBuilder();
181
        $q
182
            ->select('event')
183
            ->from($this->tableName)
184
            ->where('organizer = ?')
185
            ->setParameter(0, $organizerId);
186
187
        $results = $q->execute();
188
189
        $events = array();
190
        while ($id = $results->fetchColumn(0)) {
191
            $events[] = $id;
192
        }
193
194
        return $events;
195
    }
196
197
    /**
198
     * @inheritdoc
199
     */
200
    public function getPlaceOfEvent($eventId)
201
    {
202
        return $this->getRelationOfEvent($eventId, 'place');
203
    }
204
205
    /**
206
     * @inheritdoc
207
     */
208
    public function getOrganizerOfEvent($eventId)
209
    {
210
        return $this->getRelationOfEvent($eventId, 'organizer');
211
    }
212
213
    /**
214
     * @param string $eventId
215
     * @param string $eventType
216
     * @return string|null
217
     */
218
    private function getRelationOfEvent($eventId, $eventType)
219
    {
220
        $queryBuilder = $this->connection->createQueryBuilder();
221
222
        $queryBuilder->select(['place', 'organizer'])
223
            ->from($this->tableName)
224
            ->where('event = :eventId')
225
            ->setParameter(':eventId', $eventId);
226
227
        $statement = $queryBuilder->execute();
228
229
        $rows = $statement->fetchAll(\PDO::FETCH_ASSOC);
230
231
        return isset($rows[0][$eventType]) ? $rows[0][$eventType] : null;
232
    }
233
234 View Code Duplication
    public function removeRelations($eventId)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
235
    {
236
        $q = $this->connection->createQueryBuilder();
237
        $q->delete($this->tableName)
238
          ->where('event = ?')
239
          ->setParameter(0, $eventId);
240
241
        $q->execute();
242
    }
243
244
    /**
245
     * @param Schema $schema
246
     * @return \Doctrine\DBAL\Schema\Table|null
247
     */
248
    public function configureSchema(Schema $schema)
249
    {
250
        if ($schema->hasTable($this->tableName)) {
251
            return null;
252
        }
253
254
        return $this->configureTable();
255
    }
256
257
    public function configureTable()
258
    {
259
        $schema = new Schema();
260
261
        $table = $schema->createTable($this->tableName);
262
263
        $table->addColumn(
264
            'event',
265
            'string',
266
            array('length' => 36, 'notnull' => false)
267
        );
268
        $table->addColumn(
269
            'organizer',
270
            'string',
271
            array('length' => 36, 'notnull' => false)
272
        );
273
        $table->addColumn(
274
            'place',
275
            'string',
276
            array('length' => 36, 'notnull' => false)
277
        );
278
279
        $table->setPrimaryKey(array('event'));
280
281
        return $table;
282
    }
283
}
284