Completed
Push — master ( d6c5c0...118f52 )
by Thomas
04:57
created

EmberModelGenerator::generateRelationships()   C

Complexity

Conditions 7
Paths 24

Size

Total Lines 42
Code Lines 28

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 1 Features 0
Metric Value
c 3
b 1
f 0
dl 0
loc 42
rs 6.7272
cc 7
eloc 28
nc 24
nop 2
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
				
40
			switch ($col->getType()) {
41
				case 'NUMERIC':
42
				case 'DECIMAL':
43
				case 'TINYINT':
44
				case 'SMALLINT':
45
				case 'INTEGER':
46
				case 'BIGINT':
47
				case 'REAL':
48
				case 'FLOAT':
49
				case 'DOUBLE':
50
					$value = 'attr(\'number\')';
51
					break;
52
						
53
				case 'BOOLEAN':
54
					$value = 'attr(\'boolean\')';
55
					break;
56
						
57
				case 'TIMESTAMP':
58
					$value = 'attr(\'date\')';
59
					break;
60
						
61
				default:
62
					$value = 'attr(\'string\')';
63
			}
64
				
65
			$class->setProperty($prop, $value);
66
		}
67
	}
68
	
69
	protected function generateRelationships(EmberClassGenerator $class, Table $model) {
70
		$relationships = $this->modelService->getRelationships($model);
71
		$imports = new Set();
72
		$types = [];
73
		$multiples = [];
74
		
75
		foreach ($relationships->getAll() as $relationship) {
76
			$type = NameUtils::dasherize($relationship->getForeign()->getOriginCommonName());
77
			if (in_array($type, $types)) {
78
				$multiples[] = $type;
79
			} else {
80
				$types[] = $type;
81
			}
82
		}
83
		
84
		$multiples = array_unique($multiples);
85
		
86
		foreach ($relationships->getAll() as $relationship) {
87
			
88
			$type = NameUtils::dasherize($relationship->getForeign()->getOriginCommonName());
89
			$slug = $this->getSlug($relationship->getForeign());
90
91
			// check one-to-one
92
			if ($relationship->getType() == Relationship::ONE_TO_ONE) {
93
				$inverse = in_array($type, $multiples) ? ', {inverse: null}' : '';
94
				$prop = NameUtils::toCamelCase($relationship->getRelatedTypeName());
95
				$value = sprintf('belongsTo(\'%s/%s\'%s)', $slug, $type, $inverse);
96
				$imports->add('belongsTo');
97
			} else {
98
				$prop = NameUtils::toCamelCase($relationship->getRelatedPluralTypeName());
99
				$value = sprintf('hasMany(\'%s/%s\')', $slug, $type);
100
				$imports->add('hasMany');
101
			}
102
			
103
			$class->setProperty($prop, $value);
104
		}
105
		
106
		if ($imports->size() > 0) {
107
			$import = sprintf('{ %s }', implode(', ', $imports->toArray()));
108
			$class->addImport($import, 'ember-data/relationships');
109
		}
110
	}
111
	
112
	private function getColumnFilter(CodegenSchema $codegen, Table $model) {
113
		$read = $codegen->getReadFilter($model->getOriginCommonName());
114
		$write = $codegen->getWriteFilter($model->getOriginCommonName());
115
		
116
		$merge = [];
117
		foreach ($read as $field) {
118
			if (in_array($field, $write)) {
119
				$merge[] = $field;
120
			}
121
		}
122
		
123
		return $merge;
124
	}
125
}