MigrationCommand.php 7.75 KB
Newer Older
1 2
<?php

3
namespace App\Command;
4

5
use App\Command\GoGoAbstractCommand;
6 7
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
8 9
use App\Document\MigrationState;
use App\Document\GoGoLogUpdate;
10 11 12 13 14 15 16 17
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Process\Process;
/**
 * Command to update database when schema need migration
 * Also provide some update message in the admin dashboard
 */
class MigrationCommand extends GoGoAbstractCommand
{
Sebastian Castro's avatar
Sebastian Castro committed
18 19 20 21
    // -----------------------------------------------------------------
    // DO NOT REMOVE A SINGLE ELEMENT OF THOSE ARRAYS, ONLY ADD NEW ONES
    // -----------------------------------------------------------------
    public $migrations = [
22
      // v2.4.6
Sebastian Castro's avatar
Sebastian Castro committed
23 24 25 26 27 28
      'db.TileLayer.updateMany({name:"cartodb"}, {$set: {attribution:"&copy; <a href=\"http://www.openstreetmap.org/copyright\">OpenStreetMap</a> &copy; <a href=\"http://cartodb.com/attributions\">CartoDB</a>"}})',
      'db.TileLayer.updateMany({name:"hydda"}, {$set: {attribution:"Tiles courtesy of <a href=\"http://openstreetmap.se/\" target=\"_blank\">OpenStreetMap Sweden</a> &mdash; Map data &copy; <a href=\"http://www.openstreetmap.org/copyright\">OpenStreetMap</a>"}})',
      'db.TileLayer.updateMany({name:"wikimedia"}, {$set: {attribution:"<a href=\"https://wikimediafoundation.org/wiki/Maps_Terms_of_Use\">Wikimedia</a> | Map data © <a href=\"https://www.openstreetmap.org/copyright\">OpenStreetMap contributors</a>"}})',
      'db.TileLayer.updateMany({name:"lyrk"}, {$set: {attribution:"&copy Lyrk | Map data &copy; <a href=\"http://www.openstreetmap.org/copyright\">OpenStreetMap</a>"}})',
      'db.TileLayer.updateMany({name:"osmfr"}, {$set: {attribution:"&copy; Openstreetmap France | &copy; <a href=\"http://www.openstreetmap.org/copyright\">OpenStreetMap</a>"}})',
      'db.TileLayer.updateMany({name:"stamenWaterColor"}, {$set: {attribution:"Map tiles by <a href=\"http://stamen.com\">Stamen Design</a>, <a href=\"http://creativecommons.org/licenses/by/3.0\">CC BY 3.0</a> &mdash; Map data &copy; <a href=\"http://www.openstreetmap.org/copyright\">OpenStreetMap</a>"}})',
Sebastian Castro's avatar
Sebastian Castro committed
29 30 31 32
    ];

    public $commands = [
      // v2.3.1
Sebastian Castro's avatar
Sebastian Castro committed
33
      "app:elements:updateJson all",
Sebastian Castro's avatar
Sebastian Castro committed
34
      // v2.3.4
Sebastian Castro's avatar
Sebastian Castro committed
35 36
      "app:elements:updateJson all",
      // v2.4.5
Sebastian Castro's avatar
Sebastian Castro committed
37
      "app:elements:updateJson all"
Sebastian Castro's avatar
Sebastian Castro committed
38 39 40 41 42 43 44 45
    ];

    public $messages = [
        // v2.3.0
        "Un champ <b>Image (url)</b> est maintenant disponible dans la confiugration du formulaire !",
        "Vous pouvez désormais customizer la popup qui s'affiche au survol d'un marqueur. Allez dans Personnalisation -> Marqueur / Popup",
        "Nouvelle option pour le menu (Personnalisation -> La Carte -> onglet Menu) : afficher à côté de chaque catégories le nombre d'élements disponible pour cette catégorie",
        // v2.3.1
Sebastian Castro's avatar
Sebastian Castro committed
46
        "Vous pouvez maintenant renseigner la licence qui protège vos données dans Personnalisation -> Configuration Générale",
Sebastian Castro's avatar
Sebastian Castro committed
47
        // v2.3.4
Sebastian Castro's avatar
Sebastian Castro committed
48 49
        "Amélioration du <b>système d'import</b>: vous pouvez maintenant faire correspondre les champs et les catégories avant d'importer. Des vidéos tutoriels ont été réalisés. <u>Merci de parcourir vos imports dynamiques pour les mettre à jour avec le nouveau système</u>",
        "<b>La gestion des permissions des utilisateurs fait peau neuve !</b> <u>Votre ancienne configuration ne sera peut être plus valide</u>. Veuillez vous rendre dans le <b>menu Utilisateurs pour mettre à jour les roles des utilisateurs et des groupes</b> d'utilisateurs.",
Sebastian Castro's avatar
Sebastian Castro committed
50 51 52
        "Vous pouvez maintenant configurer des mot clés à exclure dans la recherche des éléments. Rendez-vous dans Personnalisation -> La Carte -> Onglet Recherche",
        // v2.5
        "Il est maintenant possible de <b>téléverser des images et des fichiers</b> depuis le formulaire d'ajout d'un élément ! Paramétrez ces nouveaux champs dans Modèle de Données -> Formulaire"
Sebastian Castro's avatar
Sebastian Castro committed
53 54 55
    ];


56 57 58 59 60 61 62
    protected function gogoConfigure()
    {
        $this->setName('db:migrate')
             ->setDescription('Update datatabse each time after code update');
    }

    protected function gogoExecute($em, InputInterface $input, OutputInterface $output)
63
    {
64 65 66 67 68 69 70
        $migrationState = $em->createQueryBuilder('BiopenCoreBundle:MigrationState')->getQuery()->getSingleResult();
        if ($migrationState == null) // Meaning the migration state was not yet in the place in the code
        {
            $migrationState = new MigrationState();
            $em->persist($migrationState);
        }

71 72 73
        try {
            // Collecting the Database to be updated
            $dbs = ['gogocarto_default'];
74
            $dbNames = $em->createQueryBuilder('BiopenSaasBundle:Project')->select('domainName')->hydrate(false)->getQuery()->execute()->toArray();
75
            foreach ($dbNames as $object) { $dbs[] = $object['domainName']; }
76

77 78
            if (count($this->migrations) > $migrationState->getMigrationIndex()) {
                $migrationsToRun = array_slice($this->migrations, $migrationState->getMigrationIndex());
Sebastian Castro's avatar
Sebastian Castro committed
79
                $migrationsToRun = array_unique($migrationsToRun);
80 81
                foreach($dbs as $db) {
                    foreach($migrationsToRun as $migration) {
Sebastian Castro's avatar
Sebastian Castro committed
82 83
                        $this->log("run migration " . $migration . " on project " . $db);
                        $this->runMongoCommand($db, $migration);
84
                    }
85 86 87 88
                }
                $this->log(count($migrationsToRun) . " migrations performed");
            } else {
                $this->log("No Migrations to perform");
89 90
            }

91 92 93 94 95
            $asyncService = $this->getContainer()->get('biopen.async');
            // run them syncronously otherwise all the command will be run at once
            $asyncService->setRunSynchronously(true);
            if (count($this->commands) > $migrationState->getCommandsIndex()) {
                $commandsToRun = array_slice($this->commands, $migrationState->getCommandsIndex());
96
                $commandsToRun = array_unique($commandsToRun);
Sebastian Castro's avatar
Sebastian Castro committed
97
                $this->log(count($commandsToRun) . " commands to run");
98
                foreach($dbs as $db) {
99
                    foreach($commandsToRun as $command) {
Sebastian Castro's avatar
Sebastian Castro committed
100
                        $this->log("call command " . $command . " on project " . $db);
101
                        $asyncService->callCommand($command, [], $db);
102
                    }
103 104 105
                }
            } else {
                $this->log("No commands to run");
Sebastian Castro's avatar
Sebastian Castro committed
106 107
            }

108 109
            if (count($this->messages) > $migrationState->getMessagesIndex()) {
                $messagesToAdd = array_slice($this->messages, $migrationState->getMessagesIndex());
Sebastian Castro's avatar
Sebastian Castro committed
110
                $this->log(count($messagesToAdd) . " messages to add");
111
                foreach($dbs as $db) {
Sebastian Castro's avatar
Sebastian Castro committed
112
                    $this->log("add message on project " . $db);
113
                    foreach($messagesToAdd as $message) {
114
                        // create a GoGoLogUpdate
115
                        $asyncService->callCommand('gogolog:add:message', ['"' . $message . '"'], $db);
116
                    }
117 118 119 120
                }
                $this->log(count($messagesToAdd) . " messages added to admin dashboard");
            } else {
                $this->log("No Messages to add to dashboard");
121 122
            }
        }
123 124
        catch (\Exception $e) {
            $message = $e->getMessage() . '</br>' . $e->getFile() . ' LINE ' . $e->getLine();
125
            $this->error("Error performing migrations: " . $message);
126
        }
127 128

        $migrationState->setMigrationIndex(count($this->migrations));
Sebastian Castro's avatar
Sebastian Castro committed
129
        $migrationState->setCommandsIndex(count($this->commands));
130
        $migrationState->setMessagesIndex(count($this->messages));
131
        $em->flush();
132 133
    }

Sebastian Castro's avatar
Sebastian Castro committed
134
    private function runMongoCommand($db, $command)
135
    {
Sebastian Castro's avatar
Sebastian Castro committed
136
        $process = new Process("mongo {$db} --eval '{$command}'");
137
        return $process->run();
138 139
    }
}