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

3
namespace App\Command;
4

5
use App\Document\GoGoLogUpdate;
Alan Poulain's avatar
Fix CS  
Alan Poulain committed
6 7
use App\Document\MigrationState;
use App\Services\AsyncService;
8 9
use Doctrine\ODM\MongoDB\DocumentManager;
use Psr\Log\LoggerInterface;
Alan Poulain's avatar
Fix CS  
Alan Poulain committed
10 11 12
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Process\Process;
13 14
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;

15 16
/**
 * Command to update database when schema need migration
Alan Poulain's avatar
Fix CS  
Alan Poulain committed
17
 * Also provide some update message in the admin dashboard.
18 19 20
 */
class MigrationCommand extends GoGoAbstractCommand
{
Sebastian Castro's avatar
Sebastian Castro committed
21 22 23
    // -----------------------------------------------------------------
    // DO NOT REMOVE A SINGLE ELEMENT OF THOSE ARRAYS, ONLY ADD NEW ONES
    // -----------------------------------------------------------------
Alan Poulain's avatar
Alan Poulain committed
24
    public static $migrations = [
25
      // v2.4.6
Sebastian Castro's avatar
Sebastian Castro committed
26 27 28 29 30 31
      '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
32 33
    ];

Alan Poulain's avatar
Alan Poulain committed
34
    public static $commands = [
Sebastian Castro's avatar
Sebastian Castro committed
35
      // v2.3.1
Alan Poulain's avatar
Fix CS  
Alan Poulain committed
36
      'app:elements:updateJson all',
Sebastian Castro's avatar
Sebastian Castro committed
37
      // v2.3.4
Alan Poulain's avatar
Fix CS  
Alan Poulain committed
38
      'app:elements:updateJson all',
Sebastian Castro's avatar
Sebastian Castro committed
39
      // v2.4.5
Alan Poulain's avatar
Fix CS  
Alan Poulain committed
40
      'app:elements:updateJson all',
Sebastian Castro's avatar
Sebastian Castro committed
41 42
    ];

Alan Poulain's avatar
Alan Poulain committed
43
    public static $messages = [
Sebastian Castro's avatar
Sebastian Castro committed
44
        // v2.3.0
Alan Poulain's avatar
Fix CS  
Alan Poulain committed
45
        'Un champ <b>Image (url)</b> est maintenant disponible dans la confiugration du formulaire !',
Sebastian Castro's avatar
Sebastian Castro committed
46 47 48
        "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
Alan Poulain's avatar
Fix CS  
Alan Poulain committed
49
        '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
50
        // v2.3.4
Sebastian Castro's avatar
Sebastian Castro committed
51 52
        "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.",
Alan Poulain's avatar
Fix CS  
Alan Poulain committed
53
        'Vous pouvez maintenant configurer des mot clés à exclure dans la recherche des éléments. Rendez-vous dans Personnalisation -> La Carte -> Onglet Recherche',
Sebastian Castro's avatar
Sebastian Castro committed
54
        // v2.5
Alan Poulain's avatar
Fix CS  
Alan Poulain committed
55
        "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",
56
        // v3.0
Sebastian Castro's avatar
Sebastian Castro committed
57
        "Vous pouvez maintenant écrire des actualités qui seront incluses dans la newsletter automatique! Allez dans Mails/Newsletter -> Actualités",
58 59
        "L'export des éléments depuis la page Données -> Elements fonctionne de nouveau et inclus cette fois correctement tous les champs personnalisés (y compris fichiers et images)",
        "Depuis le site, la recherche par élément peut maintenant fonctionenr sur plusieurs champs. Dans Modèle de Données -> Formulaire, editez un champ pour voir apparaitre la configuration liée à la recherche. Vous pouvez aussi donner des poids différents à chaque champs, par exemple la recherche sur le titre avec un poids de 3 et la recherche dans la description avec un poids de 1"
Sebastian Castro's avatar
Sebastian Castro committed
60 61
    ];

62 63 64 65 66 67 68
    public function __construct(DocumentManager $dm, LoggerInterface $commandsLogger,
                               TokenStorageInterface $security,
                               AsyncService $asyncService)
    {
        $this->asyncService = $asyncService;
        parent::__construct($dm, $commandsLogger, $security);
    }
Sebastian Castro's avatar
Sebastian Castro committed
69

Alan Poulain's avatar
Alan Poulain committed
70
    protected function gogoConfigure(): void
71 72 73 74 75
    {
        $this->setName('db:migrate')
             ->setDescription('Update datatabse each time after code update');
    }

Alan Poulain's avatar
Alan Poulain committed
76
    protected function gogoExecute(DocumentManager $dm, InputInterface $input, OutputInterface $output): void
77
    {
78
        $migrationState = $dm->createQueryBuilder('App\Document\MigrationState')->getQuery()->getSingleResult();
Alan Poulain's avatar
Fix CS  
Alan Poulain committed
79
        if (null == $migrationState) { // Meaning the migration state was not yet in the place in the code
80
            $migrationState = new MigrationState();
Sebastian Castro's avatar
Sebastian Castro committed
81
            $dm->persist($migrationState);
82 83
        }

84 85 86
        try {
            // Collecting the Database to be updated
            $dbs = ['gogocarto_default'];
87
            $dbNames = $dm->createQueryBuilder('App\Document\Project')->select('domainName')->hydrate(false)->getQuery()->execute()->toArray();
Alan Poulain's avatar
Fix CS  
Alan Poulain committed
88 89 90
            foreach ($dbNames as $object) {
                $dbs[] = $object['domainName'];
            }
91

Alan Poulain's avatar
Alan Poulain committed
92 93
            if (count(self::$migrations) > $migrationState->getMigrationIndex()) {
                $migrationsToRun = array_slice(self::$migrations, $migrationState->getMigrationIndex());
Sebastian Castro's avatar
Sebastian Castro committed
94
                $migrationsToRun = array_unique($migrationsToRun);
Alan Poulain's avatar
Fix CS  
Alan Poulain committed
95 96 97
                foreach ($dbs as $db) {
                    foreach ($migrationsToRun as $migration) {
                        $this->log('run migration '.$migration.' on project '.$db);
Sebastian Castro's avatar
Sebastian Castro committed
98
                        $this->runMongoCommand($db, $migration);
99
                    }
100
                }
Alan Poulain's avatar
Fix CS  
Alan Poulain committed
101
                $this->log(count($migrationsToRun).' migrations performed');
102
            } else {
Alan Poulain's avatar
Fix CS  
Alan Poulain committed
103
                $this->log('No Migrations to perform');
104 105
            }

106
            // run them syncronously otherwise all the command will be run at once
107
            $this->asyncService->setRunSynchronously(true);
Alan Poulain's avatar
Alan Poulain committed
108 109
            if (count(self::$commands) > $migrationState->getCommandsIndex()) {
                $commandsToRun = array_slice(self::$commands, $migrationState->getCommandsIndex());
110
                $commandsToRun = array_unique($commandsToRun);
Alan Poulain's avatar
Fix CS  
Alan Poulain committed
111 112 113 114
                $this->log(count($commandsToRun).' commands to run');
                foreach ($dbs as $db) {
                    foreach ($commandsToRun as $command) {
                        $this->log('call command '.$command.' on project '.$db);
115
                        $this->asyncService->callCommand($command, [], $db);
116
                    }
117 118
                }
            } else {
Alan Poulain's avatar
Fix CS  
Alan Poulain committed
119
                $this->log('No commands to run');
Sebastian Castro's avatar
Sebastian Castro committed
120 121
            }

Alan Poulain's avatar
Alan Poulain committed
122 123
            if (count(self::$messages) > $migrationState->getMessagesIndex()) {
                $messagesToAdd = array_slice(self::$messages, $migrationState->getMessagesIndex());
Alan Poulain's avatar
Fix CS  
Alan Poulain committed
124 125 126 127
                $this->log(count($messagesToAdd).' messages to add');
                foreach ($dbs as $db) {
                    $this->log('add message on project '.$db);
                    foreach ($messagesToAdd as $message) {
128
                        // create a GoGoLogUpdate
Alan Poulain's avatar
Fix CS  
Alan Poulain committed
129
                        $this->asyncService->callCommand('gogolog:add:message', ['"'.$message.'"'], $db);
130
                    }
131
                }
Alan Poulain's avatar
Fix CS  
Alan Poulain committed
132
                $this->log(count($messagesToAdd).' messages added to admin dashboard');
133
            } else {
Alan Poulain's avatar
Fix CS  
Alan Poulain committed
134
                $this->log('No Messages to add to dashboard');
135
            }
Alan Poulain's avatar
Fix CS  
Alan Poulain committed
136 137 138
        } catch (\Exception $e) {
            $message = $e->getMessage().'</br>'.$e->getFile().' LINE '.$e->getLine();
            $this->error('Error performing migrations: '.$message);
139
        }
140

Alan Poulain's avatar
Alan Poulain committed
141 142 143
        $migrationState->setMigrationIndex(count(self::$migrations));
        $migrationState->setCommandsIndex(count(self::$commands));
        $migrationState->setMessagesIndex(count(self::$messages));
Sebastian Castro's avatar
Sebastian Castro committed
144
        $dm->flush();
145 146
    }

Sebastian Castro's avatar
Sebastian Castro committed
147
    private function runMongoCommand($db, $command)
148
    {
Sebastian Castro's avatar
Sebastian Castro committed
149
        $process = new Process("mongo {$db} --eval '{$command}'");
Alan Poulain's avatar
Fix CS  
Alan Poulain committed
150

151
        return $process->run();
152
    }
Alan Poulain's avatar
Fix CS  
Alan Poulain committed
153
}