123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131 |
- <?php
- /* For licensing terms, see /license.txt */
- namespace Application\Migrations\Schema\V110;
- use Application\Migrations\AbstractMigrationChamilo;
- use Doctrine\DBAL\Schema\Schema;
- use Doctrine\DBAL\Types\Type;
- /**
- * Fix track_e_hotspot table and migrate hotspot/values
- * In the wake of an issue with the hotspot code not being possible to update without moving from AS2 to AS3 (Flash), we
- * have decided to rewrite the hotspot tool in JS.
- * Little did we know that we would find out that the coordinates system in use by the Flash version of hotspot was in
- * fact a projection into a square form of 360x360, not depending on the original size of the image, and that a square
- * was defined by its center's coordinates and its width, with an initial not-null margin on the left and top borders.
- * The migration below fixes those parallax issues.
- */
- class Version20151214170800 extends AbstractMigrationChamilo
- {
- /**
- * @param Schema $schema
- */
- public function up(Schema $schema)
- {
- $this->addSql("ALTER TABLE track_e_hotspot ADD c_id INT NULL");
- $this->addSql("ALTER TABLE track_e_hotspot MODIFY COLUMN hotspot_coordinate LONGTEXT NOT NULL");
- $this->addSql("UPDATE track_e_hotspot SET c_id = (SELECT id FROM course WHERE code = hotspot_course_code)");
- $answers = $this->connection->fetchAll("
- SELECT a.iid, a.c_id, a.question_id, a.hotspot_coordinates, a.hotspot_type, q.picture, c.directory
- FROM c_quiz_answer a
- INNER JOIN c_quiz_question q
- ON (a.question_id = q.id AND a.c_id = q.c_id)
- INNER JOIN course c
- ON (a.c_id = c.id AND q.c_id = c.id)
- WHERE a.hotspot_type IN ('square', 'circle', 'poly', 'delineation', 'oar')
- ");
- foreach ($answers as $answer) {
- // Recover the real image size to recalculate coordinates
- $imagePath = __DIR__ . "/../../../../courses/{$answer['directory']}/document/images/{$answer['picture']}";
- if (!file_exists($imagePath)) {
- error_log("Migration: Image does not exists: $imagePath");
- $imagePath = realpath($imagePath);
- error_log("Hotspot realpath: $imagePath");
- error_log("api_get_path: SYS_PATH: ".api_get_path(SYS_PATH));
- continue;
- }
- $imageSize = getimagesize($imagePath);
- $widthRatio = $imageSize[0] / 360;
- $heightRatio = $imageSize[1] / 360;
- $oldCoords = $answer['hotspot_coordinates'];
- $oldPairedString = explode('|', $oldCoords);
- $newPairedString = [];
- switch ($answer['hotspot_type']) {
- case 'square':
- $oldCenter = explode(';', $oldPairedString[0]);
- $oldCenterX = intval($oldCenter[0]);
- $oldCenterY = intval($oldCenter[1]);
- $oldWidth = intval($oldPairedString[1]);
- $oldHeight = intval($oldPairedString[2]);
- $newX = floor(($oldCenterX - $oldWidth / 2) * $widthRatio) + ceil($widthRatio);
- $newY = floor(($oldCenterY - $oldHeight / 2) * $heightRatio) + ceil($heightRatio);
- $newWidth = ceil($oldWidth * $widthRatio) + ceil(1 * $heightRatio);
- $newHeight = ceil($oldHeight * $heightRatio) + floor(1 * $heightRatio);
- $newPairedString[] = implode(';', [$newX, $newY]);
- $newPairedString[] = $newWidth;
- $newPairedString[] = $newHeight;
- break;
- case 'circle':
- $oldCenter = explode(';', $oldPairedString[0]);
- $oldCenterX = intval($oldCenter[0]);
- $oldCenterY = intval($oldCenter[1]);
- $oldRadiusX = intval($oldPairedString[1]) / 2;
- $oldRadiusY = intval($oldPairedString[2]) / 2;
- $newCenterX = floor($oldCenterX * $widthRatio) + ceil($widthRatio);
- $newCenterY = floor($oldCenterY * $heightRatio) + ceil($heightRatio);
- $newRadiusX = floor($oldRadiusX * $widthRatio);
- $newRadiusY = floor($oldRadiusY * $heightRatio);
- $newPairedString[] = implode(';', [$newCenterX, $newCenterY]);
- $newPairedString[] = $newRadiusX;
- $newPairedString[] = $newRadiusY;
- break;
- case 'poly':
- //no break;
- case 'delineation':
- //no break
- case 'oar':
- $paired = [];
- foreach ($oldPairedString as $pairString) {
- $pair = explode(';', $pairString);
- $x = isset($pair[0]) ? intval($pair[0]) : 0;
- $y = isset($pair[1]) ? intval($pair[1]) : 0;
- $paired[] = [$x, $y];
- }
- foreach ($paired as $pair) {
- $x = floor($pair[0] * $widthRatio) + ceil($widthRatio);
- $y = ceil($pair[1] * $heightRatio);
- $newPairedString[] = implode(';', [$x, $y]);
- }
- break;
- }
- $stmt = $this->connection->prepare("
- UPDATE c_quiz_answer
- SET hotspot_coordinates = :coordinates
- WHERE iid = :iid AND c_id = :cid
- ");
- $stmt->bindValue('coordinates', implode('|', $newPairedString), Type::TEXT);
- $stmt->bindValue('iid', $answer['iid'], Type::INTEGER);
- $stmt->bindValue('cid', $answer['c_id'], Type::INTEGER);
- $stmt->execute();
- }
- }
- /**
- * @param Schema $schema
- */
- public function down(Schema $schema)
- {
- }
- }
|