aboutsummaryrefslogtreecommitdiff
path: root/cli/Commands/Make/Model.php
blob: 82e683bef6ee29ab76ea146e55f0661f735b0375 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
<?php

namespace Studip\Cli\Commands\Make;

use Nette\PhpGenerator\PhpFile;
use Nette\PhpGenerator\PsrPrinter;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Question\ChoiceQuestion;


final class Model extends Command
{
    protected static $defaultName = 'make:model';

    protected function configure(): void
    {
        $this->setDescription('Create a sorm-model file');
        $this->addArgument('name', InputArgument::REQUIRED, 'The name of the sorm-model');
        $this->addArgument('db-table', InputArgument::OPTIONAL, 'The name of the related db-table');
        $this->addOption('namespace', 's', InputOption::VALUE_OPTIONAL, 'Namespace', '');
        $defaultPath = $GLOBALS['STUDIP_BASE_PATH'] . '/lib/models';
        $this->addOption(
            'path',
            'p',
            InputOption::VALUE_OPTIONAL,
            'The location where the model file should be created',
            $defaultPath
        );
    }


    protected function execute(InputInterface $input, OutputInterface $output): int
    {
        $namespace = $input->getOption('namespace');
        $name      = $input->getArgument('name');
        $dbTable   = $input->getArgument('db-table');
        $path      = $input->getOption('path');
        $verbose   = $input->getOption('verbose');

        $filename = $this->createModelFile(
            $path,
            $name,
            $input,
            $output,
            $dbTable,
            $namespace
        );

        if ($verbose) {
            $output->writeln('Model file ' . $filename . ' created.');
        }

        return Command::SUCCESS;
    }

    private function createModelFile(
        string $path,
        string $name,
        InputInterface $input,
        OutputInterface $output,
        string $dbTable = null,
        string $namespace = null,
    ): string
    {
        if (!$dbTable) {
            $dbTable = strtosnakecase($name);
        }

        $file      = new PhpFile();
        $className = str_replace(' ', '', ucwords($name));

        if ($namespace) {
            $className = ucfirst($namespace) . '\\' . $className;
        }
        $class = $file->addClass($className);
        $class->setExtends(\SimpleORMap::class);
        $class->addComment(ucfirst($name) . '.php');
        $class->addComment('model class for table ' . $dbTable);
        $method = $class->addMethod('configure')
            ->setStatic()
            ->setProtected();

        $method->addBody(sprintf('$config[\'db_table\'] = \'%s\';', $dbTable));
        $method->addBody('parent::configure($config);');
        $method->addParameter('config', []);


        $printer = new PsrPrinter();
        $result  = $printer->printFile($file);

        $modelName = str_replace(' ', '_', ucfirst($name));
        $filename  = $path . '/' . $modelName . '.php';

        file_put_contents($filename, $result);

        $helper = $this->getHelper('question');

        $tableExists = \DBManager::get()->execute('SHOW TABLES LIKE ?', [$dbTable]);

        $describeModel = false;
        if ($tableExists) {
            $question = new ChoiceQuestion(
                "\nDescribe model:\n",
                $modelName
            );
            $describeModel  = $helper->ask($input, $output, $question);
        }

        if ($describeModel) {
            $greetInput = new ArrayInput([
                'command' => 'sorm:describe',
                'name'    => 'Fabien',
                '--yell'  => true,
            ]);

            $returnCode = $this->getApplication()->doRun($greetInput, $output);
        }

        return $filename;
    }
}