1 | <?php |
||
2 | |||
3 | declare(strict_types=1); |
||
4 | |||
5 | /* |
||
6 | * @copyright 2019 Mautic, Inc. All rights reserved |
||
7 | * @author Mautic, Inc. |
||
8 | * |
||
9 | * @link https://mautic.com |
||
10 | * |
||
11 | * @license GNU/GPLv3 http://www.gnu.org/licenses/gpl-3.0.html |
||
12 | */ |
||
13 | |||
14 | namespace Mautic\IntegrationsBundle\Migration; |
||
15 | |||
16 | use Doctrine\DBAL\Schema\Schema; |
||
17 | use Doctrine\ORM\EntityManager; |
||
18 | |||
19 | abstract class AbstractMigration implements MigrationInterface |
||
20 | { |
||
21 | /** |
||
22 | * @var EntityManager |
||
23 | */ |
||
24 | protected $entityManager; |
||
25 | |||
26 | /** |
||
27 | * @var string |
||
28 | */ |
||
29 | protected $tablePrefix; |
||
30 | |||
31 | /** |
||
32 | * @var string[] |
||
33 | */ |
||
34 | private $queries = []; |
||
35 | |||
36 | public function __construct(EntityManager $entityManager, string $tablePrefix) |
||
37 | { |
||
38 | $this->entityManager = $entityManager; |
||
39 | $this->tablePrefix = $tablePrefix; |
||
40 | } |
||
41 | |||
42 | /** |
||
43 | * {@inheritdoc} |
||
44 | */ |
||
45 | public function shouldExecute(): bool |
||
46 | { |
||
47 | return $this->isApplicable($this->entityManager->getConnection()->getSchemaManager()->createSchema()); |
||
48 | } |
||
49 | |||
50 | /** |
||
51 | * {@inheritdoc} |
||
52 | * |
||
53 | * @throws \Doctrine\DBAL\DBALException |
||
54 | */ |
||
55 | public function execute(): void |
||
56 | { |
||
57 | $this->up(); |
||
58 | |||
59 | if (!$this->queries) { |
||
0 ignored issues
–
show
|
|||
60 | return; |
||
61 | } |
||
62 | |||
63 | $connection = $this->entityManager->getConnection(); |
||
64 | |||
65 | foreach ($this->queries as $sql) { |
||
66 | $stmt = $connection->prepare($sql); |
||
67 | $stmt->execute(); |
||
68 | } |
||
69 | } |
||
70 | |||
71 | /** |
||
72 | * Generate the ALTER TABLE query that adds the foreign key. |
||
73 | * |
||
74 | * @param string[] $columns |
||
75 | * @param string[] $referenceColumns |
||
76 | * @param string $suffix usually a 'ON DELETE ...' statement |
||
77 | */ |
||
78 | protected function generateAlterTableForeignKeyStatement( |
||
79 | string $table, |
||
80 | array $columns, |
||
81 | string $referenceTable, |
||
82 | array $referenceColumns, |
||
83 | string $suffix = '' |
||
84 | ): string { |
||
85 | return "ALTER TABLE {$this->concatPrefix($table)} |
||
86 | ADD CONSTRAINT {$this->generatePropertyName($table, 'fk', $columns)} |
||
87 | FOREIGN KEY ({$this->columnsToString($columns)}) |
||
88 | REFERENCES {$this->concatPrefix($referenceTable)} ({$this->columnsToString($referenceColumns)}) {$suffix} |
||
89 | "; |
||
90 | } |
||
91 | |||
92 | /** |
||
93 | * @param string[] $columns |
||
94 | */ |
||
95 | protected function generateIndexStatement(string $table, array $columns): string |
||
96 | { |
||
97 | return "INDEX {$this->generatePropertyName($table, 'idx', $columns)} ({$this->columnsToString($columns)})"; |
||
98 | } |
||
99 | |||
100 | /** |
||
101 | * @param string[] $columns |
||
102 | */ |
||
103 | protected function columnsToString(array $columns): string |
||
104 | { |
||
105 | return implode(',', $columns); |
||
106 | } |
||
107 | |||
108 | /** |
||
109 | * Generate the name for the property. |
||
110 | * |
||
111 | * This method was copied from AbstractMauticMigration. |
||
112 | * |
||
113 | * @param string[] $columnNames |
||
114 | */ |
||
115 | protected function generatePropertyName(string $table, string $type, array $columnNames): string |
||
116 | { |
||
117 | $columnNames = array_merge([$this->tablePrefix.$table], $columnNames); |
||
118 | $hash = implode( |
||
119 | '', |
||
120 | array_map( |
||
121 | function ($column) { |
||
122 | return dechex(crc32($column)); |
||
123 | }, |
||
124 | $columnNames |
||
125 | ) |
||
126 | ); |
||
127 | |||
128 | return substr(strtoupper($type.'_'.$hash), 0, 63); |
||
129 | } |
||
130 | |||
131 | protected function addSql(string $sql): void |
||
132 | { |
||
133 | $this->queries[] = $sql; |
||
134 | } |
||
135 | |||
136 | /** |
||
137 | * Concatenates table/index prefix to the provided name. |
||
138 | */ |
||
139 | protected function concatPrefix(string $name): string |
||
140 | { |
||
141 | return $this->tablePrefix.$name; |
||
142 | } |
||
143 | |||
144 | /** |
||
145 | * Define in the child migration whether the migration should be executed. |
||
146 | * Check if the migration is applied in the schema already. |
||
147 | */ |
||
148 | abstract protected function isApplicable(Schema $schema): bool; |
||
149 | |||
150 | /** |
||
151 | * Define queries for migration up. |
||
152 | */ |
||
153 | abstract protected function up(): void; |
||
154 | } |
||
155 |
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.
Consider making the comparison explicit by using
empty(..)
or! empty(...)
instead.