Failed Conditions
Push — develop ( 152bc9...e39bc0 )
by Sergei
102:42 queued 37:39
created

ForeignKeyConstraint   A

Complexity

Total Complexity 34

Size/Duplication

Total Lines 375
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 34
eloc 57
dl 0
loc 375
ccs 73
cts 73
cp 1
rs 9.68
c 0
b 0
f 0

23 Methods

Rating   Name   Duplication   Size   Complexity  
A getOption() 0 3 1
A getOptions() 0 3 1
A getQuotedForeignTableName() 0 3 1
A onUpdate() 0 3 1
A hasOption() 0 3 1
A onDelete() 0 3 1
A getUnqualifiedForeignTableName() 0 10 2
A getForeignColumns() 0 3 1
A onEvent() 0 11 3
A createIdentifierMap() 0 9 2
A setLocalTable() 0 3 1
A getForeignTableName() 0 3 1
A getUnquotedForeignColumns() 0 3 1
A getUnquotedLocalColumns() 0 3 1
A getLocalTable() 0 3 1
A getLocalTableName() 0 3 1
A getQuotedForeignColumns() 0 9 2
A getColumns() 0 3 1
A getQuotedColumns() 0 3 1
A intersectsIndexColumns() 0 11 4
A getQuotedLocalColumns() 0 9 2
A __construct() 0 16 3
A getLocalColumns() 0 3 1
1
<?php
2
3
namespace Doctrine\DBAL\Schema;
4
5
use Doctrine\DBAL\Platforms\AbstractPlatform;
6
use function array_keys;
7
use function array_map;
8
use function in_array;
9
use function strrpos;
10
use function strtolower;
11
use function strtoupper;
12
use function substr;
13
14
/**
15
 * An abstraction class for a foreign key constraint.
16
 */
17
class ForeignKeyConstraint extends AbstractAsset implements Constraint
18
{
19
    /**
20
     * Instance of the referencing table the foreign key constraint is associated with.
21
     *
22
     * @var Table
23
     */
24
    protected $_localTable;
25
26
    /**
27
     * Asset identifier instances of the referencing table column names the foreign key constraint is associated with.
28
     * array($columnName => Identifier)
29
     *
30
     * @var Identifier[]
31
     */
32
    protected $_localColumnNames;
33
34
    /**
35
     * Table or asset identifier instance of the referenced table name the foreign key constraint is associated with.
36
     *
37
     * @var Table|Identifier
38
     */
39
    protected $_foreignTableName;
40
41
    /**
42
     * Asset identifier instances of the referenced table column names the foreign key constraint is associated with.
43
     * array($columnName => Identifier)
44
     *
45
     * @var Identifier[]
46
     */
47
    protected $_foreignColumnNames;
48
49
    /**
50
     * Options associated with the foreign key constraint.
51
     *
52
     * @var mixed[]
53
     */
54
    protected $_options;
55
56
    /**
57
     * Initializes the foreign key constraint.
58
     *
59
     * @param string[]     $localColumnNames   Names of the referencing table columns.
60
     * @param Table|string $foreignTableName   Referenced table.
61
     * @param string[]     $foreignColumnNames Names of the referenced table columns.
62
     * @param string|null  $name               Name of the foreign key constraint.
63
     * @param mixed[]      $options            Options associated with the foreign key constraint.
64
     */
65
    public function __construct(array $localColumnNames, $foreignTableName, array $foreignColumnNames, $name = null, array $options = [])
66 4233
    {
67
        if ($name !== null) {
68 4233
            $this->_setName($name);
69
        }
70 3681
71 4233
        $this->_localColumnNames = $this->createIdentifierMap($localColumnNames);
72 4233
73 3658
        if ($foreignTableName instanceof Table) {
74 575
            $this->_foreignTableName = $foreignTableName;
75
        } else {
76 4233
            $this->_foreignTableName = new Identifier($foreignTableName);
77 1008
        }
78
79 3283
        $this->_foreignColumnNames = $this->createIdentifierMap($foreignColumnNames);
80
        $this->_options            = $options;
81
    }
82 4233
83 3658
    /**
84 575
     * @param string[] $names
85 4233
     *
86 4233
     * @return Identifier[]
87
     */
88
    private function createIdentifierMap(array $names) : array
89
    {
90
        $identifiers = [];
91
92
        foreach ($names as $name) {
93
            $identifiers[$name] = new Identifier($name);
94 46
        }
95
96 46
        return $identifiers;
97
    }
98
99
    /**
100
     * Returns the name of the referencing table
101
     * the foreign key constraint is associated with.
102
     *
103
     * @return string
104
     */
105
    public function getLocalTableName()
106
    {
107 2141
        return $this->_localTable->getName();
108
    }
109 2141
110 2141
    /**
111
     * Sets the Table instance of the referencing table
112
     * the foreign key constraint is associated with.
113
     *
114
     * @param Table $table Instance of the referencing table.
115 23
     *
116
     * @return void
117 23
     */
118
    public function setLocalTable(Table $table)
119
    {
120
        $this->_localTable = $table;
121
    }
122
123
    /**
124
     * @return Table
125
     */
126 2806
    public function getLocalTable()
127
    {
128 2806
        return $this->_localTable;
129
    }
130
131
    /**
132
     * Returns the names of the referencing table columns
133
     * the foreign key constraint is associated with.
134
     *
135
     * @return string[]
136
     */
137
    public function getLocalColumns()
138
    {
139
        return array_keys($this->_localColumnNames);
140
    }
141
142
    /**
143 2052
     * Returns the quoted representation of the referencing table column names
144
     * the foreign key constraint is associated with.
145 2052
     *
146
     * But only if they were defined with one or the referencing table column name
147 2052
     * is a keyword reserved by the platform.
148 2029
     * Otherwise the plain unquoted value as inserted is returned.
149
     *
150
     * @param AbstractPlatform $platform The platform to use for quotation.
151 2052
     *
152
     * @return string[]
153
     */
154
    public function getQuotedLocalColumns(AbstractPlatform $platform)
155
    {
156
        $columns = [];
157
158
        foreach ($this->_localColumnNames as $column) {
159 211
            $columns[] = $column->getQuotedName($platform);
160
        }
161 211
162
        return $columns;
163
    }
164
165
    /**
166
     * Returns unquoted representation of local table column names for comparison with other FK
167
     *
168
     * @return string[]
169 166
     */
170
    public function getUnquotedLocalColumns()
171 166
    {
172
        return array_map([$this, 'trimQuotes'], $this->getLocalColumns());
173
    }
174
175
    /**
176
     * Returns unquoted representation of foreign table column names for comparison with other FK
177
     *
178
     * @return string[]
179 2141
     */
180
    public function getUnquotedForeignColumns()
181 2141
    {
182
        return array_map([$this, 'trimQuotes'], $this->getForeignColumns());
183
    }
184
185
    /**
186
     * {@inheritdoc}
187
     *
188
     * @see getLocalColumns
189
     */
190
    public function getColumns()
191
    {
192
        return $this->getLocalColumns();
193
    }
194
195
    /**
196
     * Returns the quoted representation of the referencing table column names
197
     * the foreign key constraint is associated with.
198 230
     *
199
     * But only if they were defined with one or the referencing table column name
200 230
     * is a keyword reserved by the platform.
201
     * Otherwise the plain unquoted value as inserted is returned.
202
     *
203
     * @see getQuotedLocalColumns
204
     *
205
     * @param AbstractPlatform $platform The platform to use for quotation.
206
     *
207
     * @return string[]
208
     */
209 1684
    public function getQuotedColumns(AbstractPlatform $platform)
210
    {
211 1684
        return $this->getQuotedLocalColumns($platform);
212
    }
213
214
    /**
215
     * Returns the name of the referenced table
216
     * the foreign key constraint is associated with.
217
     *
218
     * @return string
219 166
     */
220
    public function getForeignTableName()
221 166
    {
222
        return $this->_foreignTableName->getName();
223 166
    }
224
225
    /**
226
     * Returns the non-schema qualified foreign table name.
227
     *
228
     * @return string
229
     */
230
    public function getUnqualifiedForeignTableName()
231
    {
232
        $name     = $this->_foreignTableName->getName();
233
        $position = strrpos($name, '.');
234
235
        if ($position !== false) {
236
            $name = substr($name, $position);
237
        }
238 2052
239
        return strtolower($name);
240 2052
    }
241
242
    /**
243
     * Returns the quoted representation of the referenced table name
244
     * the foreign key constraint is associated with.
245
     *
246
     * But only if it was defined with one or the referenced table name
247
     * is a keyword reserved by the platform.
248
     * Otherwise the plain unquoted value as inserted is returned.
249 1753
     *
250
     * @param AbstractPlatform $platform The platform to use for quotation.
251 1753
     *
252
     * @return string
253
     */
254
    public function getQuotedForeignTableName(AbstractPlatform $platform)
255
    {
256
        return $this->_foreignTableName->getQuotedName($platform);
257
    }
258
259
    /**
260
     * Returns the names of the referenced table columns
261
     * the foreign key constraint is associated with.
262
     *
263
     * @return string[]
264
     */
265
    public function getForeignColumns()
266 2052
    {
267
        return array_keys($this->_foreignColumnNames);
268 2052
    }
269
270 2052
    /**
271 2029
     * Returns the quoted representation of the referenced table column names
272
     * the foreign key constraint is associated with.
273
     *
274 2052
     * But only if they were defined with one or the referenced table column name
275
     * is a keyword reserved by the platform.
276
     * Otherwise the plain unquoted value as inserted is returned.
277
     *
278
     * @param AbstractPlatform $platform The platform to use for quotation.
279
     *
280
     * @return string[]
281
     */
282
    public function getQuotedForeignColumns(AbstractPlatform $platform)
283
    {
284
        $columns = [];
285 1914
286
        foreach ($this->_foreignColumnNames as $column) {
287 1914
            $columns[] = $column->getQuotedName($platform);
288
        }
289
290
        return $columns;
291
    }
292
293
    /**
294
     * Returns whether or not a given option
295
     * is associated with the foreign key constraint.
296
     *
297 275
     * @param string $name Name of the option to check.
298
     *
299 275
     * @return bool
300
     */
301
    public function hasOption($name)
302
    {
303
        return isset($this->_options[$name]);
304
    }
305
306
    /**
307 116
     * Returns an option associated with the foreign key constraint.
308
     *
309 116
     * @param string $name Name of the option the foreign key constraint is associated with.
310
     *
311
     * @return mixed
312
     */
313
    public function getOption($name)
314
    {
315
        return $this->_options[$name];
316
    }
317
318 143
    /**
319
     * Returns the options associated with the foreign key constraint.
320 143
     *
321
     * @return mixed[]
322
     */
323
    public function getOptions()
324
    {
325
        return $this->_options;
326
    }
327
328
    /**
329 120
     * Returns the referential action for UPDATE operations
330
     * on the referenced table the foreign key constraint is associated with.
331 120
     *
332
     * @return string|null
333
     */
334
    public function onUpdate()
335
    {
336
        return $this->onEvent('onUpdate');
337
    }
338
339
    /**
340
     * Returns the referential action for DELETE operations
341
     * on the referenced table the foreign key constraint is associated with.
342 143
     *
343
     * @return string|null
344 143
     */
345 69
    public function onDelete()
346
    {
347 69
        return $this->onEvent('onDelete');
348 23
    }
349
350
    /**
351
     * Returns the referential action for a given database operation
352 143
     * on the referenced table the foreign key constraint is associated with.
353
     *
354
     * @param string $event Name of the database operation/event to return the referential action for.
355
     *
356
     * @return string|null
357
     */
358
    private function onEvent($event)
359
    {
360
        if (isset($this->_options[$event])) {
361
            $onEvent = strtoupper($this->_options[$event]);
362
363
            if (! in_array($onEvent, ['NO ACTION', 'RESTRICT'])) {
364
                return $onEvent;
365 378
            }
366
        }
367 378
368 378
        return false;
0 ignored issues
show
Bug Best Practice introduced by
The expression return false returns the type false which is incompatible with the documented return type null|string.
Loading history...
369 378
    }
370 378
371
    /**
372
     * Checks whether this foreign key constraint intersects the given index columns.
373
     *
374
     * Returns `true` if at least one of this foreign key's local columns
375 92
     * matches one of the given index's columns, `false` otherwise.
376
     *
377
     * @param Index $index The index to be checked against.
378
     *
379
     * @return bool
380
     */
381
    public function intersectsIndexColumns(Index $index)
382
    {
383
        foreach ($index->getColumns() as $indexColumn) {
384
            foreach ($this->_localColumnNames as $localColumn) {
385
                if (strtolower($indexColumn) === strtolower($localColumn->getName())) {
386
                    return true;
387
                }
388
            }
389
        }
390
391
        return false;
392
    }
393
}
394