ResetGameDatabaseCommand::configure()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 1
eloc 4
c 2
b 0
f 0
nc 1
nop 0
dl 0
loc 6
ccs 0
cts 5
cp 0
crap 2
rs 10
1
<?php
2
3
namespace App\Command;
4
5
use Symfony\Component\Console\Application;
6
use Symfony\Component\Console\Attribute\AsCommand;
7
use Symfony\Component\Console\Command\Command;
8
use Symfony\Component\Console\Input\InputArgument;
9
use Symfony\Component\Console\Input\InputInterface;
10
use Symfony\Component\Console\Input\InputOption;
11
use Symfony\Component\Console\Output\OutputInterface;
12
use Symfony\Component\Console\Style\SymfonyStyle;
13
use Symfony\Component\Console\Input\ArrayInput;
14
use Symfony\Component\Filesystem\Filesystem;
15
use Symfony\Component\HttpKernel\KernelInterface;
16
17
#[AsCommand(
18
    name: 'app:reset-database',
19
    description: 'Reset the database and import data from CSV files.',
20
    hidden: false,
21
    aliases: ['app:reset-game-database']
22
)]
23
class ResetGameDatabaseCommand extends Command
24
{
25
    /**
26
     * @var KernelInterface
27
     */
28
    private $kernel;
29
30
    public function __construct(KernelInterface $kernel)
31
    {
32
        $this->kernel = $kernel;
33
        parent::__construct();
34
    }
35
36
    protected function configure(): void
37
    {
38
        $this
39
            ->setName('app:reset-database')
40
            ->setHelp('This command allows you to reset the game dataabase and import all CSV files.')
41
            ->setDescription('Reset the database and import data from CSV files.');
42
    }
43
44
    /**
45
     * Executes the command to reset the database and import data from the CSV files.
46
     *
47
     * @param InputInterface  $input  The input interface.
48
     * @param OutputInterface $output The output interface.
49
     *
50
     * @return int The command exit code.
51
     */
52
    protected function execute(InputInterface $input, OutputInterface $output): int
53
    {
54
        $io = new SymfonyStyle($input, $output);
55
56
        $csvFiles = ['location.csv', 'connection.csv', 'item.csv', 'action.csv', 'response.csv'];
57
        $csvDirectory = $this->kernel->getProjectDir() . '/' . 'public/csv';
58
59
        // Make sure files are present before attempting to reset database
60
        $missingFiles = $this->getMissingCsvFiles($csvFiles, $csvDirectory);
61
        if (!empty($missingFiles)) {
62
            $io->error('The following CSV files are missing in the ' . $csvDirectory . ' directory: ' . implode(', ', $missingFiles) . '. Aborting database reset!');
63
            return Command::FAILURE;
64
        }
65
66
        // Drop the database schema
67
        $io->section('Dropping the database schema...');
68
        $this->runCommand($output, 'doctrine:schema:drop', ['--em' => 'game', '--force' => true]);
69
70
        // Update the database schema
71
        $io->section('Updating the database schema...');
72
        $this->runCommand($output, 'doctrine:schema:update', ['--em' => 'game', '--force' => true, '--complete' => true]);
73
74
        // Import CSV files
75
        $io->section('Importing CSV files...');
76
        $output->writeln([
77
            '',
78
            ' Importing CSV files...',
79
        ]);
80
81
        foreach ($csvFiles as $filename) {
82
            $this->importCsv($output, $filename, 'game');
83
        }
84
85
        // Create message indicating successful import
86
        $fileCount = count($csvFiles);
87
        $output->setVerbosity(OutputInterface::VERBOSITY_NORMAL);
88
        $output->writeln([
89
            '',
90
            "     <info>{$fileCount}</info> CSV files imported",
91
            '',
92
        ]);
93
94
        $io->success('Database reset and data import completed!');
95
96
        return Command::SUCCESS;
97
    }
98
99
    /**
100
     * Runs a Symfony console command.
101
     *
102
     * @param OutputInterface      $output    The output interface for command output
103
     * @param string               $command   The command name
104
     * @param array<string, mixed> $arguments The command arguments
105
     * @param int                  $verbosity The desired verbosity level for command output. Default it normal.
106
     */
107
    private function runCommand(OutputInterface $output, string $command, array $arguments = [], int $verbosity = OutputInterface::VERBOSITY_NORMAL): void
108
    {
109
        /** @var Application */
110
        $application = $this->getApplication();
111
        $application->setAutoExit(false);
112
113
        $input = new ArrayInput([
114
            'command' => $command,
115
            ...$arguments,
116
        ]);
117
118
        $output->setVerbosity($verbosity); // Set the desired verbosity level
119
120
        $application->run($input, $output);
121
    }
122
123
    /**
124
     * Imports data from a CSV file using the custom import command.
125
     *
126
     * @param OutputInterface $output             The output interface for command output
127
     * @param string          $csvFile            The path to the CSV file
128
     * @param string          $entityManagerName  The name of the entity manager
129
     */
130
    private function importCsv(OutputInterface $output, string $csvFile, string $entityManagerName): void
131
    {
132
        $this->runCommand(
133
            $output,
134
            'app:import-csv',
135
            [
136
            'filename'     => $csvFile,
137
            '--manager' => $entityManagerName,
138
        ],
139
            OutputInterface::VERBOSITY_QUIET
140
        );
141
    }
142
143
    /**
144
     * @param string[] $csvFiles The array of files to see if present.
145
     * @param string   $csvDirectory The path to the csv files.
146
     *
147
     * @return string[] The missing CSV files.
148
     */
149
    private function getMissingCsvFiles(array $csvFiles, string $csvDirectory): array
150
    {
151
        $filesystem = new Filesystem();
152
        $missingFiles = [];
153
        foreach ($csvFiles as $filename) {
154
            $filePath = $csvDirectory . '/' . $filename;
155
            if (!$filesystem->exists($filePath)) {
156
                $missingFiles[] = $filename;
157
            }
158
        }
159
        return $missingFiles;
160
    }
161
}
162