Completed
Push — master ( 80e539...e8c98b )
by Kristof
11s
created

DBALRepository::eventHasRelations()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 16
rs 9.7333
c 0
b 0
f 0
cc 1
nc 1
nop 2
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
    public function storePlace($eventId, $placeId)
59
    {
60
        $this->storeRelation($eventId, 'place', $placeId);
61
    }
62
63
    /**
64
     * @param string $eventId
65
     * @param string $relationType either 'place' or 'organizer'
66
     * @param string $itemId
67
     */
68
    private function storeRelation($eventId, $relationType, $itemId)
69
    {
70
        $transaction = function ($connection) use ($eventId, $relationType, $itemId) {
71
            if ($this->eventHasRelations($connection, $eventId)) {
72
                $this->updateEventRelation($connection, $eventId, $relationType, $itemId);
73
            } else {
74
                $this->createEventRelation($connection, $eventId, $relationType, $itemId);
75
            }
76
        };
77
78
        $this->connection->transactional($transaction);
79
    }
80
81
    /**
82
     * @param Connection $connection
83
     * @param string $eventId
84
     * @param string $relationType
85
     * @param string $itemId
86
     */
87
    private function createEventRelation(
88
        Connection $connection,
89
        $eventId,
90
        $relationType,
91
        $itemId
92
    ) {
93
        $q = $connection
94
            ->createQueryBuilder()
95
            ->insert($this->tableName)
96
            ->values([
97
                'event' => ':event_id',
98
                $relationType => ':item_id',
99
            ])
100
            ->setParameter('event_id', $eventId)
101
            ->setParameter('item_id', $itemId);
102
103
        $q->execute();
104
    }
105
106
    /**
107
     * @param Connection $connection
108
     * @param string $eventId
109
     * @param string $relationType
110
     * @param string $itemId
111
     */
112
    private function updateEventRelation(
113
        Connection $connection,
114
        $eventId,
115
        $relationType,
116
        $itemId
117
    ) {
118
        $q = $connection
119
            ->createQueryBuilder()
120
            ->update($this->tableName)
121
            ->where('event = :event_id')
122
            ->set($relationType, ':item_id')
123
            ->setParameter('event_id', $eventId)
124
            ->setParameter('item_id', $itemId);
125
126
        $q->execute();
127
    }
128
129
    /**
130
     * @param Connection $connection
131
     * @param string $id
132
     * @return bool
133
     */
134
    private function eventHasRelations(
135
        Connection $connection,
136
        $id
137
    ) {
138
        $q = $connection->createQueryBuilder();
139
140
        $q->select('1')
141
            ->from($this->tableName, 'relation')
142
            ->where('relation.event = :event_id')
143
            ->setParameter('event_id', $id);
144
145
        $result = $q->execute();
146
        $relations = $result->fetchAll();
147
148
        return count($relations) > 0;
149
    }
150
151
    private function prepareInsertStatement()
152
    {
153
        $table = $this->connection->quoteIdentifier($this->tableName);
154
        return $this->connection->prepare(
155
            "INSERT INTO {$table} SET
156
              event = :event,
157
              place = :place,
158
              organizer = :organizer
159
            ON DUPLICATE KEY UPDATE
160
              place = :place,
161
              organizer=:organizer"
162
        );
163
    }
164
165 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...
166
    {
167
        $q = $this->connection->createQueryBuilder();
168
        $q->select('event')
169
          ->from($this->tableName)
170
          ->where('place = ?')
171
          ->setParameter(0, $placeId);
172
173
        $results = $q->execute();
174
175
        $events = array();
176
        while ($id = $results->fetchColumn(0)) {
177
            $events[] = $id;
178
        }
179
180
        return $events;
181
    }
182
183 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...
184
    {
185
        $q = $this->connection->createQueryBuilder();
186
        $q
187
            ->select('event')
188
            ->from($this->tableName)
189
            ->where('organizer = ?')
190
            ->setParameter(0, $organizerId);
191
192
        $results = $q->execute();
193
194
        $events = array();
195
        while ($id = $results->fetchColumn(0)) {
196
            $events[] = $id;
197
        }
198
199
        return $events;
200
    }
201
202
    /**
203
     * @inheritdoc
204
     */
205
    public function getPlaceOfEvent($eventId)
206
    {
207
        return $this->getRelationOfEvent($eventId, 'place');
208
    }
209
210
    /**
211
     * @inheritdoc
212
     */
213
    public function getOrganizerOfEvent($eventId)
214
    {
215
        return $this->getRelationOfEvent($eventId, 'organizer');
216
    }
217
218
    /**
219
     * @param string $eventId
220
     * @param string $eventType
221
     * @return string|null
222
     */
223
    private function getRelationOfEvent($eventId, $eventType)
224
    {
225
        $queryBuilder = $this->connection->createQueryBuilder();
226
227
        $queryBuilder->select(['place', 'organizer'])
228
            ->from($this->tableName)
229
            ->where('event = :eventId')
230
            ->setParameter(':eventId', $eventId);
231
232
        $statement = $queryBuilder->execute();
233
234
        $rows = $statement->fetchAll(\PDO::FETCH_ASSOC);
235
236
        return isset($rows[0][$eventType]) ? $rows[0][$eventType] : null;
237
    }
238
239 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...
240
    {
241
        $q = $this->connection->createQueryBuilder();
242
        $q->delete($this->tableName)
243
          ->where('event = ?')
244
          ->setParameter(0, $eventId);
245
246
        $q->execute();
247
    }
248
249
    /**
250
     * @param Schema $schema
251
     * @return \Doctrine\DBAL\Schema\Table|null
252
     */
253
    public function configureSchema(Schema $schema)
254
    {
255
        if ($schema->hasTable($this->tableName)) {
256
            return null;
257
        }
258
259
        return $this->configureTable();
260
    }
261
262
    public function configureTable()
263
    {
264
        $schema = new Schema();
265
266
        $table = $schema->createTable($this->tableName);
267
268
        $table->addColumn(
269
            'event',
270
            'string',
271
            array('length' => 36, 'notnull' => false)
272
        );
273
        $table->addColumn(
274
            'organizer',
275
            'string',
276
            array('length' => 36, 'notnull' => false)
277
        );
278
        $table->addColumn(
279
            'place',
280
            'string',
281
            array('length' => 36, 'notnull' => false)
282
        );
283
284
        $table->setPrimaryKey(array('event'));
285
286
        return $table;
287
    }
288
}
289