Completed
Pull Request — master (#195)
by Alejandro
10:29
created

Version20180913205455::up()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
nc 2
nop 1
dl 0
loc 12
rs 9.8666
c 0
b 0
f 0
1
<?php
2
declare(strict_types=1);
3
4
namespace ShlinkMigrations;
5
6
use Doctrine\DBAL\DBALException;
7
use Doctrine\DBAL\Schema\Schema;
8
use Doctrine\DBAL\Schema\SchemaException;
9
use Doctrine\DBAL\Types\Type;
10
use Doctrine\Migrations\AbstractMigration;
11
use Shlinkio\Shlink\Common\Exception\WrongIpException;
12
use Shlinkio\Shlink\Common\Util\IpAddress;
13
14
/**
15
 * Auto-generated Migration: Please modify to your needs!
16
 */
17
final class Version20180913205455 extends AbstractMigration
18
{
19
    /**
20
     * @param Schema $schema
21
     * @throws SchemaException
22
     */
23
    public function up(Schema $schema): void
24
    {
25
        $visits = $schema->getTable('visits');
26
        if ($visits->hasColumn('remote_addr_hash')) {
27
            return;
28
        }
29
30
        $visits->addColumn('remote_addr_hash', Type::STRING, [
31
            'notnull' => false,
32
            'length' => 128,
33
        ]);
34
    }
35
36
    /**
37
     * @param Schema $schema
38
     * @throws DBALException
39
     */
40
    public function postUp(Schema $schema)
41
    {
42
        $qb = $this->connection->createQueryBuilder();
43
        $qb->select('id', 'remote_addr', 'visit_location_id')
44
           ->from('visits');
45
        $st = $this->connection->executeQuery($qb->getSQL());
46
47
        $qb = $this->connection->createQueryBuilder();
48
        $qb->update('visits', 'v')
49
           ->set('v.remote_addr_hash', ':hash')
50
           ->set('v.remote_addr', ':obfuscatedAddr')
51
           ->where('v.id=:id');
52
53
        while ($row = $st->fetch(\PDO::FETCH_ASSOC)) {
54
            $addr = $row['remote_addr'] ?? null;
55
            if ($addr === null) {
56
                continue;
57
            }
58
59
            $qb->setParameters([
60
                'id' => $row['id'],
61
                'hash' => \hash('sha256', $addr),
62
                'obfuscatedAddr' => $this->determineAddress((string) $addr, $row),
63
            ])->execute();
64
        }
65
    }
66
67
    private function determineAddress(string $addr, array $row): ?string
68
    {
69
        // When the visit has already been located, drop the IP address
70
        if (isset($row['visit_location_id'])) {
71
            return null;
72
        }
73
74
        if ($addr === IpAddress::LOCALHOST) {
75
            return $addr;
76
        }
77
78
        try {
79
            return (string) IpAddress::fromString($addr)->getObfuscatedCopy();
80
        } catch (WrongIpException $e) {
81
            return null;
82
        }
83
    }
84
85
    /**
86
     * @param Schema $schema
87
     * @throws SchemaException
88
     */
89
    public function down(Schema $schema): void
90
    {
91
        $visits = $schema->getTable('visits');
92
        $visits->dropColumn('remote_addr_hash');
93
    }
94
}
95