Completed
Push — master ( 88c0f4...cde43d )
by Thomas
04:21
created

ModelDomainTraitGenerator   C

Complexity

Total Complexity 17

Size/Duplication

Total Lines 253
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 20

Importance

Changes 3
Bugs 0 Features 0
Metric Value
wmc 17
c 3
b 0
f 0
lcom 1
cbo 20
dl 0
loc 253
rs 6.4705

9 Methods

Rating   Name   Duplication   Size   Complexity  
B generate() 0 31 4
B generateEvent() 0 68 4
A generateCreate() 0 19 2
A generateUpdate() 0 22 2
A generateDelete() 0 15 1
A generateToOneRelationshipSet() 0 19 1
A generateToManyRelationshipAdd() 0 20 1
A generateToManyRelationshipUpdate() 0 23 1
A generateToManyRelationshipRemove() 0 20 1
1
<?php
2
namespace keeko\tools\generator\domain\base;
3
4
use gossi\codegen\model\PhpMethod;
5
use gossi\codegen\model\PhpParameter;
6
use gossi\codegen\model\PhpTrait;
7
use keeko\framework\utils\NameUtils;
8
use keeko\tools\model\ManyRelationship;
9
use keeko\tools\model\Relationship;
10
use Propel\Generator\Model\Table;
11
use gossi\codegen\model\PhpClass;
12
use gossi\codegen\model\PhpProperty;
13
14
class ModelDomainTraitGenerator extends ReadOnlyModelDomainTraitGenerator {
15
	
16
	public function generate(Table $model) {
17
		$trait = parent::generate($model);
18
		
19
		$event = $this->generateEvent($model);
20
		$trait->addUseStatement($event->getQualifiedName());
21
22
		$this->generateCreate($trait, $model);
23
		$this->generateUpdate($trait, $model);
24
		$this->generateDelete($trait, $model);
25
		
26
		
27
		
28
		// generate relationship methods
29
		if (!$model->isReadOnly()) {
30
			$relationships = $this->modelService->getRelationships($model);
31
			
32
			// to-one relationships
33
			foreach ($relationships->getOne() as $one) {
34
				$this->generateToOneRelationshipSet($trait, $one);
35
			}
36
37
			// to-many relationships
38
			foreach ($relationships->getMany() as $many) {
39
				$this->generateToManyRelationshipAdd($trait, $many);
40
				$this->generateToManyRelationshipUpdate($trait, $many);
41
				$this->generateToManyRelationshipRemove($trait, $many);
42
			}
43
		}
44
45
		return $trait;
46
	}
47
	
48
	/**
49
	 * 
50
	 * @param Table $model
51
	 * @return PhpClass
52
	 */
53
	protected function generateEvent(Table $model) {
54
		$package = $this->packageService->getPackage();
55
		$slug = $package->getKeeko()->getModule()->getSlug();
56
		$modelName = $model->getOriginCommonName();
57
		
58
		$class = new PhpClass();
59
		$class->setNamespace(str_replace('model', 'event', $model->getNamespace()));
60
		$class->setName($model->getPhpName() . 'Event');
61
		$class->addUseStatement($model->getNamespace() . '\\' . $model->getPhpName());
62
		
63
		// constants
64
		$class->setConstant('PRE_CREATE', sprintf('%s.%s.pre_create', $slug, $modelName));
65
		$class->setConstant('POST_CREATE', sprintf('%s.%s.post_create', $slug, $modelName));
66
		$class->setConstant('PRE_UPDATE', sprintf('%s.%s.pre_update', $slug, $modelName));
67
		$class->setConstant('POST_UPDATE', sprintf('%s.%s.post_update', $slug, $modelName));
68
		$class->setConstant('PRE_SAVE', sprintf('%s.%s.pre_save', $slug, $modelName));
69
		$class->setConstant('POST_SAVE', sprintf('%s.%s.post_save', $slug, $modelName));
70
		$class->setConstant('PRE_DELETE', sprintf('%s.%s.pre_delete', $slug, $modelName));
71
		$class->setConstant('POST_DELETE', sprintf('%s.%s.post_delete', $slug, $modelName));
72
		
73
		// generate relationship constants
74
		if (!$model->isReadOnly()) {
75
			$relationships = $this->modelService->getRelationships($model);
76
				
77
			// to-one relationships
78
			foreach ($relationships->getOne() as $one) {
79
				$snake = NameUtils::toSnakeCase($one->getRelatedName());
80
				$name = strtoupper($snake);
81
				$class->setConstant('PRE_' . $name . '_UPDATE', sprintf('%s.%s.pre_%s_update', $slug, $modelName, $snake));
82
				$class->setConstant('POST_' . $name . '_UPDATE', sprintf('%s.%s.post_%s_update', $slug, $modelName, $snake));
83
			}
84
		
85
			// to-many relationships
86
			foreach ($relationships->getMany() as $many) {
87
				$snake = NameUtils::toSnakeCase($many->getRelatedName());
88
				$name = strtoupper($snake);
89
				$class->setConstant('PRE_' . $name . '_ADD', sprintf('%s.%s.pre_%s_add', $slug, $modelName, $snake));
90
				$class->setConstant('POST_' . $name . '_ADD', sprintf('%s.%s.post_%s_add', $slug, $modelName, $snake));
91
				$class->setConstant('PRE_' . $name . '_UPDATE', sprintf('%s.%s.pre_%s_update', $slug, $modelName, $snake));
92
				$class->setConstant('POST_' . $name . '_UPDATE', sprintf('%s.%s.post_%s_update', $slug, $modelName, $snake));
93
				$class->setConstant('PRE_' . $name . '_REMOVE', sprintf('%s.%s.pre_%s_add', $slug, $modelName, $snake));
94
				$class->setConstant('POST_' . $name . '_REMOVE', sprintf('%s.%s.post_%s_add', $slug, $modelName, $snake));
95
			}
96
		}
97
		
98
		// properties
99
		$modelVariableName = $model->getCamelCaseName();
100
		$class->setProperty(PhpProperty::create($modelVariableName)
101
			->setType($model->getPackage())
102
			->setVisibility(PhpProperty::VISIBILITY_PROTECTED)
103
		);
104
		
105
		// constructor
106
		$class->setMethod(PhpMethod::create('__construct')
107
			->addParameter(PhpParameter::create($modelVariableName)->setType($model->getPhpName()))
108
			->setBody('$this->' . $modelVariableName . ' = ' . $modelVariableName .';')
109
		);
110
		
111
		// getModel()
112
		$class->setMethod(PhpMethod::create('get' . $model->getPhpName())
113
			->setType($model->getPhpName())
114
			->setBody('return $this->' . $modelVariableName .';')
115
		);
116
		
117
		$this->codegenService->dumpStruct($class, true);
118
		
119
		return $class;
120
	}
121
	
122
	protected function generateCreate(PhpTrait $trait, Table $model) {
123
		$trait->addUseStatement('keeko\\framework\\domain\\payload\\Created');
124
		$trait->addUseStatement('keeko\\framework\\domain\\payload\\NotFound');
125
		
126
		if ($model->hasBehavior('validate')) {
127
			$trait->addUseStatement('keeko\\framework\\domain\\payload\\NotValid');
128
		}
129
	
130
		$trait->setMethod(PhpMethod::create('create')
131
			->addParameter(PhpParameter::create('data'))
132
			->setBody($this->twig->render('create.twig', [
133
				'model' => NameUtils::toCamelCase($model->getOriginCommonName()),
134
				'class' => $model->getPhpName(),
135
				'validate' => $model->hasBehavior('validate')
136
			]))
137
			->setDescription('Creates a new ' . $model->getPhpName() . ' with the provided data')
138
			->setType('PayloadInterface')
139
		);
140
	}
141
	
142
	protected function generateUpdate(PhpTrait $trait, Table $model) {
143
		$trait->addUseStatement('keeko\\framework\\domain\\payload\\Updated');
144
		$trait->addUseStatement('keeko\\framework\\domain\\payload\\NotUpdated');
145
		$trait->addUseStatement('keeko\\framework\\domain\\payload\\NotFound');
146
		
147
		if ($model->hasBehavior('validate')) {
148
			$trait->addUseStatement('keeko\\framework\\domain\\payload\\NotValid');
149
		}
150
		
151
		$trait->setMethod(PhpMethod::create('update')
152
			->addParameter(PhpParameter::create('id'))
153
			->addParameter(PhpParameter::create('data'))
154
			->setBody($this->twig->render('update.twig', [
155
				'model' => NameUtils::toCamelCase($model->getOriginCommonName()),
156
				'class' => $model->getPhpName(),
157
				'validate' => $model->hasBehavior('validate')
158
			]))
159
			->setDescription('Updates a ' . $model->getPhpName() . ' with the given id' .
160
				'and the provided data')
161
			->setType('PayloadInterface')
162
		);
163
	}
164
	
165
	protected function generateDelete(PhpTrait $trait, Table $model) {
166
		$trait->addUseStatement('keeko\\framework\\domain\\payload\\Deleted');
167
		$trait->addUseStatement('keeko\\framework\\domain\\payload\\NotDeleted');
168
		$trait->addUseStatement('keeko\\framework\\domain\\payload\\NotFound');
169
		
170
		$trait->setMethod(PhpMethod::create('delete')
171
			->addParameter(PhpParameter::create('id'))
172
			->setBody($this->twig->render('delete.twig', [
173
				'model' => NameUtils::toCamelCase($model->getOriginCommonName()),
174
				'class' => $model->getPhpName()
175
			]))
176
			->setDescription('Deletes a ' . $model->getPhpName() . ' with the given id')
177
			->setType('PayloadInterface')
178
		);
179
	}
180
	
181
	protected function generateToOneRelationshipSet(PhpTrait $trait, Relationship $relationship) {
182
		$model = $relationship->getModel();
183
		$foreign = $relationship->getForeign();
184
		$name = $relationship->getRelatedName();
185
		$localId = NameUtils::toCamelCase($name) . 'Id';
186
		$trait->setMethod(PhpMethod::create('set' . $name . 'Id')
187
			->setDescription(str_replace('{foreign}', $foreign->getPhpName(), 'Sets the {foreign} id'))
188
			->addParameter(PhpParameter::create('id'))
189
			->addParameter(PhpParameter::create($localId))
190
			->setBody($this->twig->render('to-one-set.twig', [
191
				'model' => NameUtils::toCamelCase($model->getOriginCommonName()),
192
				'class' => $model->getPhpName(),
193
				'fk_id' => $localId,
194
				'local' => $relationship->getForeignKey()->getLocalColumn()->getPhpName(),
195
				'const' => strtoupper(NameUtils::toSnakeCase($relationship->getRelatedName()))
196
			]))
197
			->setType('PayloadInterface')
198
		);
199
	}
200
	
201
	protected function generateToManyRelationshipAdd(PhpTrait $trait, ManyRelationship $relationship) {
202
		$trait->addUseStatement('keeko\\framework\\domain\\payload\\NotValid');
203
		
204
		$model = $relationship->getModel();
205
		$foreign = $relationship->getForeign();
206
		$trait->addUseStatement($foreign->getNamespace() . '\\' . $foreign->getPhpName() . 'Query');
207
		$trait->setMethod(PhpMethod::create('add' . $relationship->getRelatedName())
208
			->setDescription('Adds ' . $foreign->getPhpName() . ' to ' . $model->getPhpName())
209
			->addParameter(PhpParameter::create('id'))
210
			->addParameter(PhpParameter::create('data'))
211
			->setBody($this->twig->render('to-many-add.twig', [
212
				'model' => $model->getCamelCaseName(),
213
				'class' => $model->getPhpName(),				
214
				'foreign_model' => $foreign->getCamelCaseName(),
215
				'foreign_class' => $foreign->getPhpName(),
216
				'const' => strtoupper(NameUtils::toSnakeCase($relationship->getRelatedName()))
217
			]))
218
			->setType('PayloadInterface')
219
		);
220
	}
221
	
222
	protected function generateToManyRelationshipUpdate(PhpTrait $trait, ManyRelationship $relationship) {
223
		$trait->addUseStatement('keeko\\framework\\domain\\payload\\NotValid');
224
		
225
		$model = $relationship->getModel();
226
		$foreign = $relationship->getForeign();
227
		$middle = $relationship->getMiddle();
228
		$trait->addUseStatement($middle->getNamespace() . '\\' . $middle->getPhpName() . 'Query');
229
		$trait->addUseStatement($foreign->getNamespace() . '\\' . $foreign->getPhpName() . 'Query');
230
		$trait->setMethod(PhpMethod::create('update' . $relationship->getRelatedName())
231
			->setDescription('Updates ' . $foreign->getPhpName() . ' on ' . $model->getPhpName())
232
			->addParameter(PhpParameter::create('id'))
233
			->addParameter(PhpParameter::create('data'))
234
			->setBody($this->twig->render('to-many-update.twig', [
235
				'model' => $model->getCamelCaseName(),
236
				'class' => $model->getPhpName(),
237
				'foreign_model' => $foreign->getCamelCaseName(),
238
				'foreign_class' => $foreign->getPhpName(),
239
				'middle_class' => $middle->getPhpName(),
240
				'const' => strtoupper(NameUtils::toSnakeCase($relationship->getRelatedName()))
241
			]))
242
			->setType('PayloadInterface')
243
		);
244
	}
245
	
246
	protected function generateToManyRelationshipRemove(PhpTrait $trait, ManyRelationship $relationship) {
247
		$trait->addUseStatement('keeko\\framework\\domain\\payload\\NotValid');
248
		
249
		$model = $relationship->getModel();
250
		$foreign = $relationship->getForeign();
251
		$trait->addUseStatement($foreign->getNamespace() . '\\' . $foreign->getPhpName() . 'Query');
252
		$trait->setMethod(PhpMethod::create('remove' . $relationship->getRelatedName())
253
			->setDescription('Removes ' . $foreign->getPhpName() . ' from ' . $model->getPhpName())
254
			->addParameter(PhpParameter::create('id'))
255
			->addParameter(PhpParameter::create('data'))
256
			->setBody($this->twig->render('to-many-remove.twig', [
257
				'model' => $model->getCamelCaseName(),
258
				'class' => $model->getPhpName(),
259
				'foreign_model' => $foreign->getCamelCaseName(),
260
				'foreign_class' => $foreign->getPhpName(),
261
				'const' => strtoupper(NameUtils::toSnakeCase($relationship->getRelatedName()))
262
			]))
263
			->setType('PayloadInterface')
264
		);
265
	}
266
}