Passed
Pull Request — master (#51)
by Damien
02:47
created

UpdateHelper::checkAuditTable()   C

Complexity

Conditions 12
Paths 96

Size

Total Lines 64
Code Lines 37

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 12
eloc 37
nc 96
nop 2
dl 0
loc 64
rs 6.9666
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace DH\DoctrineAuditBundle\Helper;
4
5
use DH\DoctrineAuditBundle\AuditConfiguration;
6
use DH\DoctrineAuditBundle\AuditManager;
7
use Doctrine\DBAL\Schema\AbstractSchemaManager;
8
use Doctrine\DBAL\Schema\Schema;
9
use Doctrine\DBAL\Schema\Table;
10
use Doctrine\DBAL\Types\Type;
11
use Doctrine\ORM\EntityManager;
12
13
class UpdateHelper
14
{
15
    /**
16
     * @var AuditManager
17
     */
18
    private $manager;
19
20
    /**
21
     * @param AuditManager $manager
22
     */
23
    public function __construct(AuditManager $manager)
24
    {
25
        $this->manager = $manager;
26
    }
27
28
    /**
29
     * @return \DH\DoctrineAuditBundle\AuditConfiguration
30
     */
31
    public function getConfiguration(): AuditConfiguration
32
    {
33
        return $this->manager->getConfiguration();
34
    }
35
36
    public function createAuditTable(Schema $schema, Table $table): void
37
    {
38
        $entityTablename = $table->getName();
39
        $regex = sprintf('#^(%s\.)(.*)$#', preg_quote($schema->getName(), '#'));
40
        if (preg_match($regex, $entityTablename)) {
41
            // entityTablename already prefixed with schema name
42
            $auditTablename = preg_replace(
43
                $regex,
44
                sprintf(
45
                    '$1%s$2%s',
46
                    preg_quote($this->getConfiguration()->getTablePrefix(), '#'),
47
                    preg_quote($this->getConfiguration()->getTableSuffix(), '#')
48
                ),
49
                $entityTablename
50
            );
51
        } else {
52
            $auditTablename = $this->getConfiguration()->getTablePrefix().$table->getName().$this->getConfiguration()->getTableSuffix();
53
        }
54
55
        if (null !== $auditTablename && !$schema->hasTable($auditTablename)) {
56
            $auditTable = $schema->createTable($auditTablename);
57
58
            // Add columns to audit table
59
            foreach ($this->manager->getHelper()->getAuditTableColumns() as $name => $struct) {
60
                $auditTable->addColumn($name, $struct['type'], $struct['options']);
61
            }
62
63
            // Add indices to audit table
64
            foreach ($this->manager->getHelper()->getAuditTableIndices($auditTablename) as $column => $struct) {
65
                if ('primary' === $struct['type']) {
66
                    $auditTable->setPrimaryKey([$column]);
67
                } else {
68
                    $auditTable->addIndex([$column], $struct['name']);
69
                }
70
            }
71
        }
72
    }
73
74
    public function checkAuditTable(AbstractSchemaManager $schemaManager, Table $table): array
75
    {
76
        $columns = $schemaManager->listTableColumns($table->getName());
77
        $expected = $this->manager->getHelper()->getAuditTableColumns();
78
79
        $add = [];
80
        $update = [];
81
        $remove = [];
82
        $processed = [];
83
84
        foreach ($columns as $column) {
85
            if (array_key_exists($column->getName(), $expected)) {
86
                // column is part of expected columns, check its properties
87
                if ($column->getType()->getName() !== $expected[$column->getName()]['type']) {
88
                    // column type is different
89
                    $update[] = [
90
                        'column' => $column,
91
                        'metadata' => $expected[$column->getName()],
92
                    ];
93
                } else {
94
                    foreach ($expected[$column->getName()]['options'] as $key => $value) {
95
                        $method = 'get'.ucfirst($key);
96
                        if (method_exists($column, $method)) {
97
                            if ($value !== $column->{$method}()) {
98
                                $update[] = [
99
                                    'column' => $column,
100
                                    'metadata' => $expected[$column->getName()],
101
                                ];
102
                            }
103
                        }
104
                    }
105
                }
106
            } else {
107
                // column is not part of expected columns so it has to be removed
108
                $remove[] = [
109
                    'column' => $column,
110
                ];
111
            }
112
113
            $processed[] = $column->getName();
114
        }
115
116
        foreach ($expected as $column => $struct) {
117
            if (!\in_array($column, $processed, true)) {
118
                $add[] = [
119
                    'column' => $column,
120
                    'metadata' => $struct,
121
                ];
122
            }
123
        }
124
125
        $operations = [];
126
127
        if (!empty($add)) {
128
            $operations['add'] = $add;
129
        }
130
        if (!empty($update)) {
131
            $operations['update'] = $update;
132
        }
133
        if (!empty($remove)) {
134
            $operations['remove'] = $remove;
135
        }
136
137
        return $operations;
138
    }
139
140
    public function updateAuditTable(AbstractSchemaManager $schemaManager, Table $table, array $operations, EntityManager $em): void
141
    {
142
        $fromSchema = $schemaManager->createSchema();
143
        $toSchema = clone $fromSchema;
144
145
        $table = $toSchema->getTable($table->getName());
146
147
        if (isset($operations['add'])) {
148
            foreach ($operations['add'] as $operation) {
149
                $table->addColumn($operation['column'], $operation['metadata']['type'], $operation['metadata']['options']);
150
            }
151
        }
152
153
        if (isset($operations['update'])) {
154
            foreach ($operations['update'] as $operation) {
155
                $table->changeColumn($operation['column']->getName(), $operation['metadata']['options']);
156
            }
157
        }
158
159
        if (isset($operations['remove'])) {
160
            foreach ($operations['remove'] as $operation) {
161
                $table->dropColumn($operation['column']->getName());
162
            }
163
        }
164
165
        $sql = $fromSchema->getMigrateToSql($toSchema, $schemaManager->getDatabasePlatform());
166
        foreach ($sql as $query) {
167
            $statement = $em->getConnection()->prepare($query);
168
            $statement->execute();
169
        }
170
    }
171
}
172