Passed
Push — master ( f762ef...190e8a )
by Julito
09:11
created

Version20151214170800   A

Complexity

Total Complexity 13

Size/Duplication

Total Lines 111
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 67
dl 0
loc 111
rs 10
c 0
b 0
f 0
wmc 13

2 Methods

Rating   Name   Duplication   Size   Complexity  
C up() 0 98 12
A down() 0 2 1
1
<?php
2
/* For licensing terms, see /license.txt */
3
4
namespace Chamilo\CoreBundle\Migrations\Schema\V110;
5
6
use Chamilo\CoreBundle\Migrations\AbstractMigrationChamilo;
7
use Doctrine\DBAL\Schema\Schema;
8
use Doctrine\DBAL\Types\Type;
9
10
/**
11
 * Fix track_e_hotspot table and migrate hotspot/values
12
 * In the wake of an issue with the hotspot code not being possible to update without moving from AS2 to AS3 (Flash), we
13
 * have decided to rewrite the hotspot tool in JS.
14
 * Little did we know that we would find out that the coordinates system in use by the Flash version of hotspot was in
15
 * fact a projection into a square form of 360x360, not depending on the original size of the image, and that a square
16
 * was defined by its center's coordinates and its width, with an initial not-null margin on the left and top borders.
17
 * The migration below fixes those parallax issues.
18
 */
19
class Version20151214170800 extends AbstractMigrationChamilo
20
{
21
    /**
22
     * @param Schema $schema
23
     */
24
    public function up(Schema $schema)
25
    {
26
        $this->addSql("ALTER TABLE track_e_hotspot ADD c_id INT NULL");
27
        $this->addSql("ALTER TABLE track_e_hotspot MODIFY COLUMN hotspot_coordinate LONGTEXT NOT NULL");
28
        $this->addSql("UPDATE track_e_hotspot SET c_id = (SELECT id FROM course WHERE code = hotspot_course_code)");
29
30
        $answers = $this->connection->fetchAll("
31
            SELECT a.iid, a.c_id, a.question_id, a.hotspot_coordinates, a.hotspot_type, q.picture, c.directory
32
            FROM c_quiz_answer a
33
            INNER JOIN c_quiz_question q
34
            ON (a.question_id = q.id AND a.c_id = q.c_id)
35
            INNER JOIN course c
36
            ON (a.c_id = c.id AND q.c_id = c.id)
37
            WHERE a.hotspot_type IN ('square', 'circle', 'poly', 'delineation', 'oar')
38
        ");
39
40
        foreach ($answers as $answer) {
41
            // Recover the real image size to recalculate coordinates
42
            $imagePath = __DIR__ . "/../../../../courses/{$answer['directory']}/document/images/{$answer['picture']}";
43
            if (!file_exists($imagePath)) {
44
                error_log("Migration: Image does not exists: $imagePath");
45
                $imagePath = realpath($imagePath);
46
                error_log("Hotspot realpath: $imagePath");
47
                error_log("api_get_path: SYS_PATH: ".api_get_path(SYS_PATH));
48
                continue;
49
            }
50
            $imageSize = getimagesize($imagePath);
51
            $widthRatio = $imageSize[0] / 360;
52
            $heightRatio = $imageSize[1] / 360;
53
            $oldCoords = $answer['hotspot_coordinates'];
54
            $oldPairedString = explode('|', $oldCoords);
55
            $newPairedString = [];
56
57
            switch ($answer['hotspot_type']) {
58
                case 'square':
59
                    $oldCenter = explode(';', $oldPairedString[0]);
60
                    $oldCenterX = intval($oldCenter[0]);
61
                    $oldCenterY = intval($oldCenter[1]);
62
                    $oldWidth = intval($oldPairedString[1]);
63
                    $oldHeight = intval($oldPairedString[2]);
64
65
                    $newX = floor(($oldCenterX - $oldWidth / 2) * $widthRatio) + ceil($widthRatio);
66
                    $newY = floor(($oldCenterY - $oldHeight / 2) * $heightRatio) + ceil($heightRatio);
67
                    $newWidth = ceil($oldWidth * $widthRatio) + ceil(1 * $heightRatio);
68
                    $newHeight = ceil($oldHeight * $heightRatio) + floor(1 * $heightRatio);
69
70
                    $newPairedString[] = implode(';', [$newX, $newY]);
71
                    $newPairedString[] = $newWidth;
72
                    $newPairedString[] = $newHeight;
73
                    break;
74
                case 'circle':
75
                    $oldCenter = explode(';', $oldPairedString[0]);
76
                    $oldCenterX = intval($oldCenter[0]);
77
                    $oldCenterY = intval($oldCenter[1]);
78
                    $oldRadiusX = intval($oldPairedString[1]) / 2;
79
                    $oldRadiusY = intval($oldPairedString[2]) / 2;
80
81
                    $newCenterX = floor($oldCenterX * $widthRatio) + ceil($widthRatio);
82
                    $newCenterY = floor($oldCenterY * $heightRatio) + ceil($heightRatio);
83
                    $newRadiusX = floor($oldRadiusX * $widthRatio);
84
                    $newRadiusY = floor($oldRadiusY * $heightRatio);
85
86
                    $newPairedString[] = implode(';', [$newCenterX, $newCenterY]);
87
                    $newPairedString[] = $newRadiusX;
88
                    $newPairedString[] = $newRadiusY;
89
                    break;
90
                case 'poly':
91
                    //no break;
92
                case 'delineation':
93
                    //no break
94
                case 'oar':
95
                    $paired = [];
96
                    foreach ($oldPairedString as $pairString) {
97
                        $pair = explode(';', $pairString);
98
                        $x = isset($pair[0]) ? intval($pair[0]) : 0;
99
                        $y = isset($pair[1]) ? intval($pair[1]) : 0;
100
101
                        $paired[] = [$x, $y];
102
                    }
103
104
                    foreach ($paired as $pair) {
105
                        $x = floor($pair[0] * $widthRatio) + ceil($widthRatio);
106
                        $y = ceil($pair[1] * $heightRatio);
107
108
                        $newPairedString[] = implode(';', [$x, $y]);
109
                    }
110
                    break;
111
            }
112
113
            $stmt = $this->connection->prepare("
114
                UPDATE c_quiz_answer
115
                SET hotspot_coordinates = :coordinates
116
                WHERE iid = :iid AND c_id = :cid
117
            ");
118
            $stmt->bindValue('coordinates', implode('|', $newPairedString), Type::TEXT);
119
            $stmt->bindValue('iid', $answer['iid'], Type::INTEGER);
120
            $stmt->bindValue('cid', $answer['c_id'], Type::INTEGER);
121
            $stmt->execute();
122
        }
123
    }
124
125
    /**
126
     * @param Schema $schema
127
     */
128
    public function down(Schema $schema)
129
    {
130
    }
131
}
132