Completed
Push — master ( c7b947...966759 )
by Thomas
08:09
created

EmberModelGenerator::generateColumns()   C

Complexity

Conditions 14
Paths 14

Size

Total Lines 38
Code Lines 28

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 38
rs 5.0864
cc 14
eloc 28
nc 14
nop 2

How to fix   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\tools\generator\AbstractCodeGenerator;
5
use Propel\Generator\Model\Table;
6
use keeko\tools\services\CommandService;
7
use keeko\tools\model\Project;
8
use keeko\framework\schema\CodegenSchema;
9
use keeko\framework\utils\NameUtils;
10
use phootwork\collection\Set;
11
12
class EmberModelGenerator extends AbstractCodeGenerator {
13
	
14
	private $prj;
15
	
16
	public function __construct(CommandService $service, Project $project) {
17
		parent::__construct($service);
18
		$this->prj = $project;
19
	}
20
	
21
	public function generate(Table $model) {
22
		$class = new EmberClassGenerator('Model');
23
		$class->addImport('Model', 'ember-data/model');
24
		$class->addImport('attr', 'ember-data/attr');
25
		
26
		// columns
27
		$this->generateColumns($class, $model);
28
		
29
		// relationships
30
		$this->generateRelationships($class, $model);
31
		
32
		return $class->generate();
33
	}
34
	
35
	protected function generateColumns(EmberClassGenerator $class, Table $model) {
36
		$codegen = $this->getCodegen();
37
		$filter = $this->getColumnFilter($codegen, $model);
38
		foreach ($model->getColumns() as $col) {
39
			if (in_array($col, $filter)) {
40
				continue;
41
			}
42
				
43
			$prop = NameUtils::toCamelCase($col->getPhpName());
44
				
45
			switch ($col->getType()) {
46
				case 'NUMERIC':
47
				case 'DECIMAL':
48
				case 'TINYINT':
49
				case 'SMALLINT':
50
				case 'INTEGER':
51
				case 'BIGINT':
52
				case 'REAL':
53
				case 'FLOAT':
54
				case 'DOUBLE':
55
					$value = 'attr(\'number\')';
56
					break;
57
						
58
				case 'BOOLEAN':
59
					$value = 'attr(\'boolean\')';
60
					break;
61
						
62
				case 'DATE':
63
					$value = 'attr(\'date\')';
64
					break;
65
						
66
				default:
67
					$value = 'attr(\'string\')';
68
			}
69
				
70
			$class->setProperty($prop, $value);
71
		}
72
	}
73
	
74
	protected function generateRelationships(EmberClassGenerator $class, Table $model) {
75
		$relationships = $this->modelService->getRelationships($model);
76
		$imports = new Set();
77
		
78
		foreach ($relationships->getAll() as $relationship) {
79
			$prop = NameUtils::toCamelCase($relationship->getRelatedTypeName());
80
			$type = NameUtils::dasherize($relationship->getForeign()->getOriginCommonName());
81
			$slug = $this->getSlug($relationship->getForeign());
82
			
83
			// check one-to-one
84
			$oneToOne = false;
85
			if ($relationship->getType() == 'one') {
86
				$foreign = $relationship->getForeign();
87
				$rel = $this->modelService->getRelationship($foreign, $model->getOriginCommonName());
88
				$oneToOne = $rel != null;
89
			}
90
			
91
			if ($oneToOne) {
92
				$value = sprintf('belongsTo(\'%s/%s\')', $slug, $type);
93
				$imports->add('belongsTo');
94
			} else {
95
				$value = sprintf('hasMany(\'%s/%s\')', $slug, $type);
96
				$imports->add('hasMany');
97
			}
98
			
99
			$class->setProperty($prop, $value);
100
		}
101
		
102
		if ($imports->size() > 0) {
103
			$import = sprintf('{ %s }', implode(', ', $imports->toArray()));
104
			$class->addImport($import, 'ember-data/relationships');
105
		}
106
	}
107
	
108
	protected function getSlug(Table $model) {
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
109
		$namespace = $model->getNamespace();
110
		$parts = explode('\\', $namespace);
111
		
112
		if ($parts[0] == 'keeko') {
113
			return $parts[1];
114
		}
115
		
116
		return $parts[0] . '.' . $parts[1];
117
	}
118
	
119
	/**
120
	 * @return CodegenSchema
121
	 */
122
	private function getCodegen() {
123
		if ($this->prj->hasCodegenFile()) {
124
			return CodegenSchema::fromFile($this->prj->getCodegenFileName());
125
		}
126
		
127
		return new CodegenSchema();
128
	}
129
	
130
	private function getColumnFilter(CodegenSchema $codegen, Table $model) {
131
		$read = $codegen->getReadFilter($model->getOriginCommonName());
132
		$write = $codegen->getWriteFilter($model->getOriginCommonName());
133
		
134
		$merge = [];
135
		foreach ($read as $field) {
136
			if (in_array($field, $write)) {
137
				$merge[] = $field;
138
			}
139
		}
140
		
141
		return $merge;
142
	}
143
}