Completed
Push — master ( c5048d...43a701 )
by Thomas
06:21
created

CodeGeneratorService::mapToCode()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 12
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 3.072

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 12
rs 9.4285
ccs 4
cts 5
cp 0.8
cc 3
eloc 7
nc 4
nop 1
crap 3.072
1
<?php
2
namespace keeko\tools\services;
3
4
use gossi\codegen\generator\CodeFileGenerator;
5
use gossi\codegen\model\AbstractPhpStruct;
6
use gossi\docblock\tags\AuthorTag;
7
use keeko\framework\schema\CodegenSchema;
8
use keeko\framework\schema\PackageSchema;
9
use keeko\tools\utils\NamespaceResolver;
10
use phootwork\file\File;
11
use phootwork\file\Path;
12
use Propel\Generator\Model\Table;
13
14
class CodeGeneratorService extends AbstractService {
15
16
	private $codegen;
0 ignored issues
show
Unused Code introduced by
The property $codegen is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
17
18
	public function getCodegenFile() {
19 7
		return $this->project->getCodegenFileName();
20 7
	}
21 7
22
	/**
23
	 * Returns codegen from project
24
	 *
25
	 * @throws JsonEmptyException
26
	 * @throws \RuntimeException
27
	 * @return CodegenSchema
28
	 */
29
	public function getCodegen() {
30
		return $this->project->getCodegen();
31 12
	}
32 7
33 7
	/**
34 7
	 * Adds authors to the docblock of the given struct
35
	 *
36 7
	 * @param AbstractPhpStruct $struct
37 12
	 * @param PackageSchema $package
38
	 */
39
	public function addAuthors(AbstractPhpStruct $struct, PackageSchema $package = null) {
40
		if ($package === null) {
41
			$package = $this->packageService->getPackage();
42
		}
43
		$docblock = $struct->getDocblock();
44
45
		foreach ($package->getAuthors() as $author) {
46
			/* @var $author AuthorSchema */
47
			$tag = AuthorTag::create()->setName($author->getName());
48
			$mail = $author->getEmail();
49
50
			if (!empty($mail)) {
51
				$tag->setEmail($mail);
52
			}
53
54
			$docblock->appendTag($tag);
55
		}
56
	}
57
58
	/**
59
	 * Returns code for hydrating a propel model
60
	 *
61
	 * @param string $modelName
62
	 * @return string
63
	 */
64
	public function getWriteFields($modelName) {
65 15
		$codegen = $this->getCodegen();
66 15
		$filter = $codegen->getWriteFilter($modelName);
67
		$model = $this->modelService->getModel($modelName);
68 15
		$computed = $this->getComputedFields($model);
69
		$filter = array_merge($filter, $computed);
70
71 15
		$fields = [];
72 15
		$cols = $model->getColumns();
73 15
		foreach ($cols as $col) {
74
			$prop = $col->getName();
75 15
76
			if (!in_array($prop, $filter)) {
77 15
				$fields[] = $prop;
78
			}
79
		}
80
81 15
		return $fields;
82 15
	}
83 15
84
	/**
85
	 * Returns the fields for a model
86
	 *
87
	 * @param string $modelName
88
	 * @return array
89
	 */
90
	public function getReadFields($modelName) {
91 5
		$codegen = $this->getCodegen();
92 5
		$model = $this->modelService->getModel($modelName);
93 5
// 		$computed = $this->getComputedFields($model);
0 ignored issues
show
Unused Code Comprehensibility introduced by
59% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
94 5
		$filter = $codegen->getReadFilter($modelName);
95 5
// 		$filter = array_merge($filter, $computed);
0 ignored issues
show
Unused Code Comprehensibility introduced by
54% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
96 5
97 5
		$fields = [];
98
		$cols = $model->getColumns();
99 5
		foreach ($cols as $col) {
100 5
			$prop = $col->getName();
101 5
102 5
			if (!in_array($prop, $filter) && !$col->isForeignKey() && !$col->isPrimaryKey()) {
103
				$fields[] = $prop;
104 5
			}
105 5
		}
106
107 5
		return $fields;
108
	}
109
110
	/**
111 5
	 * Returns computed model fields
112 5
	 *
113 5
	 * @param Table $table
114
	 * @return array<string>
115 5
	 */
116 5
	public function getComputedFields(Table $table) {
117 5
		$fields = [];
118
119 5
		// iterate over behaviors to get their respective columns
120
		foreach ($table->getBehaviors() as $behavior) {
121
			switch ($behavior->getName()) {
122
				case 'timestampable':
123
					$fields[] = $behavior->getParameter('create_column');
124
					$fields[] = $behavior->getParameter('update_column');
125
					break;
126
127
				case 'aggregate_column':
128
					$fields[] = $behavior->getParameter('name');
129
					break;
130
			}
131
		}
132
133
		return $fields;
134
	}
135
136
	/**
137
	 * Returns all attributes that aren't written onto a model (because manually filter or computed)
138
	 *
139
	 * @param Table $model
140
	 * @return array
141
	 */
142
	public function getWriteFilter(Table $model) {
143
		$modelName = $model->getOriginCommonName();
144
		$codegen = $this->getCodegen();
145
		$filter = $codegen->getWriteFilter($modelName);
146
		$computed = $this->getComputedFields($model);
147
		return array_merge($filter, $computed);
148
	}
149
150 5
	/**
151 5
	 * Helper to represent an array as php code
152
	 *
153
	 * @param array $array
154 5
	 * @return string
155 5
	 */
156 5
	public function arrayToCode(array $array) {
157 5
		$fields = '';
158 5
		foreach ($array as $item) {
159 5
			$fields .= sprintf("'%s', ", $item);
160
		}
161 5
162
		if (strlen($fields) > 0) {
163
			$fields = substr($fields, 0, -2);
164 5
		}
165 5
166
		return sprintf('[%s]', $fields);
167 5
	}
168
169
	public function mapToCode(array $array) {
170
		$fields = '';
171
		foreach ($array as $key => $value) {
172
			$fields .= sprintf("\t'%s' => '%s',\n", $key, $value);
173
		}
174
175
		if (strlen($fields) > 0) {
176 2
			$fields = substr($fields, 0, -2);
177 2
		}
178 2
179
		return sprintf("[\n%s\n]", $fields);
180 2
	}
181
182 2
	/**
183
	 * Returns the filename for a given struct
184
	 *
185
	 * @param AbstractPhpStruct $struct
186 2
	 * @return string
187
	 */
188
	public function getFilename(AbstractPhpStruct $struct) {
189 15
		$package = $this->packageService->getPackage();
190 15
		$relativeSourcePath = NamespaceResolver::getSourcePath($struct->getNamespace(), $package);
191 15
192
		if ($relativeSourcePath === null) {
193 15
			return null;
194
		}
195
196
		$jsonFile = $this->project->getComposerFileName();
197 15
		$path = new Path(dirname($jsonFile));
198 15
		$path = $path->append($relativeSourcePath);
199 15
		$path = $path->append($struct->getName() . '.php');
200 15
		return $path->toString();
201 15
	}
202
203
	/**
204 15
	 * Returns a file object for a given struct
205 15
	 *
206 15
	 * @param AbstractPhpStruct $struct
207
	 * @return File
208 15
	 */
209
	public function getFile(AbstractPhpStruct $struct) {
210 15
		return new File($this->getFilename($struct));
211 15
	}
212
213
	public function dumpStruct(AbstractPhpStruct $struct, $overwrite = false) {
214 15
		$filename = $this->getFilename($struct);
215
		$file = new File($filename);
216
217 15
		if ($filename !== null && ($file->exists() ? $overwrite : true)) {
218 15
			// generate code
219 15
			$generator = new CodeFileGenerator();
220
			$code = $generator->generate($struct);
0 ignored issues
show
Documentation introduced by
$struct is of type object<gossi\codegen\model\AbstractPhpStruct>, but the function expects a object<gossi\codegen\model\GenerateableInterface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
221
222
			// write code to file
223
			$file->write($code);
224
225
			// tell user about
226
			$this->io->writeln(sprintf('Class <info>%s</info> written at <info>%s</info>', $struct->getQualifiedName(), $filename));
227
		}
228
	}
229
}
230