Completed
Push — master ( dd800d...af5658 )
by Thomas
07:26
created

GenerateDomainCommand::interact()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
c 3
b 0
f 0
dl 0
loc 6
rs 9.4285
cc 1
eloc 4
nc 1
nop 2
1
<?php
2
namespace keeko\tools\command;
3
4
use keeko\tools\generator\domain\base\ModelDomainTraitGenerator;
5
use keeko\tools\generator\domain\base\ReadOnlyModelDomainTraitGenerator;
6
use keeko\tools\generator\domain\ModelDomainGenerator;
7
use keeko\tools\generator\domain\SkeletonDomainGenerator;
8
use keeko\tools\helpers\QuestionHelperTrait;
9
use keeko\tools\ui\DomainUI;
10
use keeko\tools\utils\NamespaceResolver;
11
use phootwork\lang\Text;
12
use Symfony\Component\Console\Input\InputArgument;
13
use Symfony\Component\Console\Input\InputInterface;
14
use Symfony\Component\Console\Input\InputOption;
15
use Symfony\Component\Console\Output\OutputInterface;
16
17
class GenerateDomainCommand extends AbstractKeekoCommand {
18
19
	use QuestionHelperTrait;
20
	
21
	private $twig;
22
23
	protected function configure() {
24
		$this
25
			->setName('generate:domain')
26
			->setDescription('Generates a domain object')
27
			->addArgument(
28
				'name',
29
				InputArgument::OPTIONAL,
30
				'The name of the action, which should be generated. Typically in the form %nomen%-%verb% (e.g. user-create)'
31
			)
32
			->addOption(
33
				'model',
34
				'm',
35
				InputOption::VALUE_OPTIONAL,
36
				'The model for which the actions should be generated, when there is no name argument (if ommited all models will be generated)'
37
			)
38
		;
39
		
40
		$this->configureGenerateOptions();
41
		
42
		parent::configure();
43
	}
44
45
	protected function initialize(InputInterface $input, OutputInterface $output) {
46
		parent::initialize($input, $output);
47
48
		$loader = new \Twig_Loader_Filesystem($this->service->getConfig()->getTemplateRoot() . '/domain');
49
		$this->twig = new \Twig_Environment($loader);
50
	}
51
52
	/**
53
	 * Checks whether actions can be generated at all by reading composer.json and verify
54
	 * all required information are available
55
	 */
56
	private function preCheck() {
57
		$module = $this->packageService->getModule();
58
		if ($module === null) {
59
			throw new \DomainException('No module definition found in composer.json - please run `keeko init`.');
60
		}
61
	}
62
	
63
	protected function interact(InputInterface $input, OutputInterface $output) {
64
		$this->preCheck();
65
		
66
		$ui = new DomainUI($this);
67
		$ui->show();
68
	}
69
70
	protected function execute(InputInterface $input, OutputInterface $output) {
71
		$this->preCheck();
72
		
73
		// 1. find out which action(s) to generate
74
		// 2. generate the information in the package
75
		// 3. generate the code for the action
76
		
77
		$name = $input->getArgument('name');
78
		$model = $input->getOption('model');
79
80
		// generate a skeleton
81
		if ($name) {
82
			$this->generateSkeleton($name);
83
		}
84
85
		// create domain for one model
86
		else if ($model) {
87
			$this->generateModel($model);
88
		}
89
90
		// generate domain for all models
91
		else {
92
			foreach ($this->modelService->getModels() as $model) {
93
				$modelName = $model->getOriginCommonName();
94
				$input->setOption('model', $modelName);
95
				$this->generateModel($modelName);
96
			}
97
		}
98
	}
99
100
	private function generateModel($modelName) {
101
		$this->logger->info('Generate Domain from Model: ' . $modelName);
102
		$model = $this->modelService->getModel($modelName);
103
		
104
		// generate class
105
		$generator = new ModelDomainGenerator($this->service);
106
		$class = $generator->generate($model);
107
		$this->codegenService->dumpStruct($class, true);
108
		
109
		// generate trait
110
		$generator = $model->isReadOnly()
111
			? new ReadOnlyModelDomainTraitGenerator($this->service)
112
			: new ModelDomainTraitGenerator($this->service);
113
		$trait = $generator->generate($model);
114
		$this->codegenService->dumpStruct($trait, true);
115
	}
116
	
117
	private function generateSkeleton($name) {
118
		$this->logger->info('Generate Skeleton Domain: ' . $name);
119
		$input = $this->io->getInput();
120
121
		$className = NamespaceResolver::getNamespace('src/domain', $this->package) . '\\' . $name;
122
		
123
		if (!Text::create($className)->endsWith('Domain')) {
124
			$className .= 'Domain';
125
		}
126
127
		// generate code
128
		$generator = new SkeletonDomainGenerator($this->service);
129
		$class = $generator->generate($className);
130
		$this->codegenService->dumpStruct($class, $input->getOption('force'));
131
	}
132
	
133
}
134