Completed
Push — master ( 118f52...c5048d )
by Thomas
10:09
created

EmberModelGenerator::collectInverseRelationships()   C

Complexity

Conditions 13
Paths 65

Size

Total Lines 51
Code Lines 27

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 1 Features 0
Metric Value
c 1
b 1
f 0
dl 0
loc 51
rs 5.6547
cc 13
eloc 27
nc 65
nop 1

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
namespace keeko\tools\generator\ember;
3
4
use keeko\framework\schema\CodegenSchema;
5
use keeko\framework\utils\NameUtils;
6
use keeko\tools\model\Relationship;
7
use phootwork\collection\Set;
8
use Propel\Generator\Model\Table;
9
10
class EmberModelGenerator extends AbstractEmberGenerator {
11
12
	public function generate(Table $model) {
13
		$class = new EmberClassGenerator('Model');
14
		$class->addImport('Model', 'ember-data/model');
15
		$class->addImport('attr', 'ember-data/attr');
16
17
		// columns
18
		$this->generateColumns($class, $model);
19
20
		// relationships
21
		$this->generateRelationships($class, $model);
22
23
		return $class->generate();
24
	}
25
26
	protected function generateColumns(EmberClassGenerator $class, Table $model) {
27
		$codegen = $this->getCodegen();
28
		$filter = $this->getColumnFilter($codegen, $model);
29
		foreach ($model->getColumns() as $col) {
30
			if (in_array($col, $filter)) {
31
				continue;
32
			}
33
34
			if ($col->isForeignKey() || $col->isPrimaryKey()) {
35
				continue;
36
			}
37
38
			$prop = NameUtils::toCamelCase($col->getPhpName());
39
			$default = null;
40
41
			switch ($col->getType()) {
42
				case 'NUMERIC':
43
				case 'DECIMAL':
44
				case 'TINYINT':
45
				case 'SMALLINT':
46
				case 'INTEGER':
47
				case 'BIGINT':
48
				case 'REAL':
49
				case 'FLOAT':
50
				case 'DOUBLE':
51
					$type = 'number';
52
					$defaultValue = $col->getDefaultValueString();
53
					if ($defaultValue != '0' && $defaultValue != 'null') {
54
						$default = $defaultValue;
55
					}
56
					break;
57
58
				case 'BOOLEAN':
59
					$type = 'boolean';
60
					$defaultValue = $col->getDefaultValueString();
61
					if ($defaultValue == 'false' || $defaultValue == 'true') {
62
						$default = $defaultValue;
63
					}
64
					break;
65
66
				case 'TIMESTAMP':
67
					$type = 'date';
68
					break;
69
70
				default:
71
					$type = 'string';
72
					$defaultValue = $col->getDefaultValueString();
73
					if ($defaultValue != 'null') {
74
						$default = $defaultValue;
75
					}
76
			}
77
78
			$value = sprintf('attr(\'%s\'%s)', $type,
79
				$default !== null ? ', {defaultValue: ' . $default . '}' : '');
80
81
			$class->setProperty($prop, $value);
82
		}
83
	}
84
85
	protected function generateRelationships(EmberClassGenerator $class, Table $model) {
86
		$relationships = $this->modelService->getRelationships($model);
87
		$imports = new Set();
88
		$inverses = $this->collectInverseRelationships($model);
89
90
		foreach ($relationships->getAll() as $relationship) {
91
			$type = NameUtils::dasherize($relationship->getForeign()->getOriginCommonName());
92
			$slug = $this->getSlug($relationship->getForeign());
93
94
			if ($relationship->getType() == Relationship::ONE_TO_ONE) {
95
				$prop = NameUtils::toCamelCase($relationship->getRelatedName());
96
				$inverse = isset($inverses[$prop]) ? ', {inverse: ' . $inverses[$prop] . '}' : '';
97
				$value = sprintf('belongsTo(\'%s/%s\'%s)', $slug, $type, $inverse);
98
				$imports->add('belongsTo');
99
			} else {
100
				$prop = NameUtils::toCamelCase($relationship->getRelatedPluralName());
101
				$inverse = isset($inverses[$prop]) ? ', {inverse: ' . $inverses[$prop] . '}' : '';
102
				$value = sprintf('hasMany(\'%s/%s\'%s)', $slug, $type, $inverse);
103
				$imports->add('hasMany');
104
			}
105
106
			$class->setProperty($prop, $value);
107
108
			if ($relationship->getType() == Relationship::MANY_TO_MANY && $relationship->isReflexive()) {
109
				$inverse = NameUtils::toCamelCase($relationship->getRelatedPluralName());
110
				$prop = NameUtils::toCamelCase($relationship->getReverseRelatedPluralTypeName());
111
				$value = sprintf('hasMany(\'%s/%s\', {inverse: \'%s\'})', $slug, $type, $inverse);
112
				$class->setProperty($prop, $value);
113
			}
114
		}
115
116
		if ($imports->size() > 0) {
117
			$import = sprintf('{ %s }', implode(', ', $imports->toArray()));
118
			$class->addImport($import, 'ember-data/relationships');
119
		}
120
	}
121
122
	private function collectInverseRelationships(Table $model) {
123
		$relationships = $this->modelService->getRelationships($model);
124
		$inverses = [];
125
126
		// find reflexive relationships
127
		foreach ($relationships->getAll() as $relationship) {
128
129
			// find reflexive one-to-many relationships
130
			if ($relationship->getType() == Relationship::ONE_TO_MANY && $relationship->isReflexive()) {
131
				$prop = NameUtils::toCamelCase($relationship->getRelatedPluralName());
132
				$inverses[$prop] = '\'' . NameUtils::toCamelCase($relationship->getReverseRelatedName()) . '\'';
133
134
				// reverse inverse
135
				$prop = NameUtils::toCamelCase($relationship->getReverseRelatedName());
136
				$inverses[$prop] = '\'' . NameUtils::toCamelCase($relationship->getRelatedPluralName()) . '\'';
137
			}
138
139
			// find reflexive many-to-many relationships
140
			if ($relationship->getType() == Relationship::MANY_TO_MANY && $relationship->isReflexive()) {
141
				$prop = NameUtils::toCamelCase($relationship->getRelatedPluralName());
142
				$inverses[$prop] = '\''.NameUtils::toCamelCase($relationship->getReverseRelatedPluralName()) . '\'';
143
			}
144
		}
145
146
		$dupes = [];
147
		foreach ($relationships->getAll() as $relationship) {
148
			$rels = $this->modelService->getRelationships($relationship->getForeign());
149
150
			// find null inverse one-to-one relationships
151
			foreach ($rels->getOneToOne() as $rel) {
152
				if ($rel->getForeign() == $model) {
153
					$prop = NameUtils::toCamelCase($relationship->getRelatedName());
154
					if (in_array($prop, $dupes) && !isset($inverses[$prop])) {
155
						$inverses[$prop] = 'null';
156
					} else {
157
						$dupes[] = $prop;
158
					}
159
				}
160
			}
161
162
			// find inverse one-to-many relationship
163
			foreach ($rels->getOneToMany() as $rel) {
164
				if ($rel->getForeign() == $model) {
165
					$prop = NameUtils::toCamelCase($rel->getReverseRelatedName());
166
					$inverses[$prop] = '\'' . NameUtils::toCamelCase($rel->getRelatedPluralName()) . '\'';
167
				}
168
			}
169
		}
170
171
		return $inverses;
172
	}
173
174
	private function getColumnFilter(CodegenSchema $codegen, Table $model) {
175
		$read = $codegen->getReadFilter($model->getOriginCommonName());
176
		$write = $codegen->getWriteFilter($model->getOriginCommonName());
177
178
		$merge = [];
179
		foreach ($read as $field) {
180
			if (in_array($field, $write)) {
181
				$merge[] = $field;
182
			}
183
		}
184
185
		return $merge;
186
	}
187
}