Edexml::_convertTeacher()   B
last analyzed

Complexity

Conditions 7
Paths 24

Size

Total Lines 35
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 7
eloc 20
c 1
b 0
f 0
nc 24
nop 1
dl 0
loc 35
rs 8.6666
1
<?php
2
App::uses('AppModel', 'Model');
3
App::uses('Xml', 'Utility');
4
5
/**
6
 * Edexml Model.
7
 *
8
 */
9
class Edexml extends AppModel {
0 ignored issues
show
Bug introduced by
The type AppModel was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
10
11
/**
12
 * Use table
13
 *
14
 * @var mixed False or table name
15
 */
16
	public $useTable = false;
17
18
/**
19
 * The (translation) domain to be used for extracted validation messages in models.
20
 *
21
 * @var string
22
 */
23
	public $validationDomain = 'edexml';
24
25
/**
26
 * Validation rules
27
 *
28
 * @var array
29
 */
30
	public $validate = [
31
		'file' => [
32
			'uploadError' => [
33
				'rule' => 'uploadError',
34
				'message' => 'File upload failed',
35
				'last' => true
36
			],
37
			'extension' => [
38
				'rule' => ['extension', ['xml']],
39
				'message' => 'Must be a xml file',
40
				'last' => true
41
			],
42
			'fileSize' => [
43
				'rule' => ['fileSize', '<=', '1MB'],
44
				'message' => 'Must be smaller than 1MB',
45
				'last' => true
46
			],
47
			'mimeType' => [
48
				'rule' => ['mimeType', ['application/xml', 'text/xml']],
49
				'message' => 'Must be of type `xml`'
50
			],
51
			'edexml' => [
52
				'rule' => 'validateEdexml',
53
				'message' => 'Must be a valid Edexml file'
54
			]
55
		]
56
	];
57
58
/**
59
 * Year group to grade mapping
60
 *
61
 * @var array
62
 */
63
	protected $_yearGroupToGradeMapping = [
64
		'B' => 1,			// Baby's leeftijd 0 tot 12 maanden
65
		'D' => 1,			// Dreumesen leeftijd 1 tot 2 jaar
66
		0 => 1,				// Peutergroep / Kleutergroep 1
67
		1 => 1,				// Groep 1 / Kleutergroep 2
68
		2 => 2,				// Groep 2 / Kleutergroep 3
69
		3 => 3,				// Groep 3 / Klas 1
70
		4 => 4,				// Groep 4 / Klas 2
71
		5 => 5,				// Groep 5 / Klas 3
72
		6 => 6,				// Groep 6 / Klas 4
73
		7 => 7,				// Groep 7 / Klas 5
74
		8 => 8,				// Groep 8 / Klas 6
75
		11 => 9,			// Voortgezet onderwijs leerjaar 1 / Secundair onderwijs leerjaar 1 (Vlaanderen)
76
		12 => 10,			// Voortgezet onderwijs leerjaar 2 / Secundair onderwijs leerjaar 2 (Vlaanderen)
77
		13 => 11,			// Voortgezet onderwijs leerjaar 3 / Secundair onderwijs leerjaar 3 (Vlaanderen)
78
		14 => 12,			// Voortgezet onderwijs leerjaar 4 / Secundair onderwijs leerjaar 4 (Vlaanderen)
79
		15 => 13,			// Voortgezet onderwijs leerjaar 5 / Secundair onderwijs leerjaar 5 (Vlaanderen)
80
		16 => 14,			// Voortgezet onderwijs leerjaar 6 / Secundair onderwijs leerjaar 6 (Vlaanderen)
81
		'S' => 19,		// S(B)O (speciaal (basis)onderwijs / BuO (buitengewoon kleuter/lager onderwijs, Vlaanderen)
82
		'V' => null,	// VSO (voortgezet speciaal onderwijs) / BuSO (buitengewoon secundair onderwijs, Vlaanderen)
83
		'C' => null,	// Combinatiegroep (jaargroep per leerling vastgelegd)
84
		'N' => 19,		// Niet PO / VO
85
		'H' => null		// Historisch
86
	];
87
88
/**
89
 * School Classes
90
 *
91
 * @var array
92
 */
93
	protected $_schoolClasses = [];
94
95
/**
96
 * An Edexml file validation function to be used in Models.
97
 *
98
 * @param array $check Model data for a file upload ('field' => 'value')
99
 * @return bool Whether or not the Edexml file is valid
100
 */
101
	public function validateEdexml($check) {
102
		$value = array_shift($check);
103
104
		return (bool)$this->_parse($value['tmp_name']);
105
	}
106
107
/**
108
 * Convert XML file to DOMDocument and validate against Edexml XSD
109
 *
110
 * @param string $filename Filename of XML file
111
 * @return bool|DOMDocument A DOMDocument, or false on validation errors
112
 */
113
	protected function _parse($filename) {
114
		if (!file_exists($filename)) {
115
			return false;
116
		}
117
118
		// Enable user error handling
119
		libxml_use_internal_errors(true);
120
		libxml_clear_errors();
121
122
		$dom = Xml::build($filename, ['return' => 'domdocument']);
123
		if (!$dom) {
124
			return false;
125
		}
126
127
		$schemaFile = CakePlugin::path('Edexml') . 'File' . DS . 'EDEXML-2.1' . DS . 'EDEXML.structuur.xsd';
0 ignored issues
show
Bug introduced by
The type CakePlugin was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
Bug introduced by
The constant DS was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
128
		if (!$dom->schemaValidate($schemaFile)) {
129
			foreach (libxml_get_errors() as $error) {
130
				CakeLog::error($this->_displayXmlError($error), 'debug');
0 ignored issues
show
Bug introduced by
The type CakeLog was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
131
			}
132
133
			libxml_clear_errors();
134
135
			return false;
136
		}
137
138
		return $dom;
139
	}
140
141
/**
142
 * Parse XML into array
143
 *
144
 * @param string $filename Filename of XML file to parse
145
 * @return mixed data (array), or false (boolean) on failure
146
 */
147
	public function parseToArray($filename) {
148
		$data = $this->_parse($filename);
149
		if ($data) {
150
			$data = Xml::toArray($data);
151
		}
152
153
		return $data;
154
	}
155
156
/**
157
 * Convert libXMLError to human-readable string
158
 *
159
 * @param libXMLError $error A libXMLError error
160
 * @return string Human-readable string
161
 */
162
	protected function _displayXmlError($error) {
163
		$return = '';
164
		$return .= str_repeat('-', $error->column) . "^\n";
165
166
		switch ($error->level) {
167
			case LIBXML_ERR_WARNING:
168
				$return .= "Warning $error->code: ";
169
				break;
170
			case LIBXML_ERR_ERROR:
171
				$return .= "Error $error->code: ";
172
				break;
173
			case LIBXML_ERR_FATAL:
174
				$return .= "Fatal Error $error->code: ";
175
				break;
176
		}
177
178
		$return .= trim($error->message) .
179
			"\n  Line: $error->line" .
180
			"\n  Column: $error->column";
181
182
		return "$return\n\n--------------------------------------------\n\n";
183
	}
184
185
/**
186
 * Convert Edexml key to reusable key
187
 *
188
 * @param string $key Edexml key
189
 * @return mixed Edexml key (string), or null (null) when key is not reusable
190
 */
191
	protected function _convertKey($key) {
192
		$result = null;
193
		if (is_string($key) && substr($key, 0, 1) !== '#') {
194
			$result = $key;
195
		}
196
197
		return $result;
198
	}
199
200
/**
201
 * Extract names (first and last name) from user element in extracted Edexml data
202
 *
203
 * @param array $user User element from extracted Edexml data
204
 * @return array Normalized data (first name and last name)
205
 */
206
	protected function _convertNames($user) {
207
		$result = [
208
			'first_name' => '',
209
			'last_name' => ''
210
		];
211
212
		if (!empty($user['voorvoegsel'])) {
213
			$result['last_name'] .= $user['voorvoegsel'] . ' ';
214
		}
215
		if (!empty($user['achternaam'])) {
216
			$result['last_name'] .= $user['achternaam'];
217
		}
218
219
		if (empty($result['first_name']) && !empty($user['roepnaam'])) {
220
			$result['first_name'] = $user['roepnaam'];
221
		}
222
		if (empty($result['first_name']) && !empty($user['voornamen'])) {
223
			$result['first_name'] = $user['voornamen'];
224
		}
225
		if (empty($result['first_name']) && !empty($user['voorletters-1'])) {
226
			$result['first_name'] = $user['voorletters-1'];
227
		}
228
229
		return $result;
230
	}
231
232
/**
233
 * Convert school element in extracted Edexml data to normalized data
234
 *
235
 * @param array $school School element from extracted Edexml data
236
 * @return array Normalized data
237
 */
238
	protected function _convertSchool($school) {
239
		$result = [
240
			'key' => null
241
		];
242
		if (!empty($school['schoolkey'])) {
243
			$result['key'] = $this->_convertKey($school['schoolkey']);
244
		}
245
246
		return $result;
247
	}
248
249
/**
250
 * Convert school class element in extracted Edexml data to normalized data
251
 *
252
 * @param array $schoolClass School class element from extracted Edexml data
253
 * @return array Normalized data
254
 */
255
	protected function _convertSchoolClass($schoolClass) {
256
		$result = [
257
			'key' => null,
258
			'grade' => null
259
		];
260
		if (!empty($schoolClass['@key'])) {
261
			$result['key'] = $this->_convertKey($schoolClass['@key']);
262
		}
263
		$result['name'] = $schoolClass['naam'];
264
		$result['grade'] = $this->_yearGroupToGradeMapping[$schoolClass['jaargroep']];
265
266
		return $result;
267
	}
268
269
/**
270
 * Convert school element in extracted Edexml data to normalized data
271
 *
272
 * @param array $schoolClasses School classes element from extracted Edexml data
273
 * @return array Normalized data
274
 */
275
	protected function _convertSchoolClasses($schoolClasses) {
276
		$result = [];
277
		if (!empty($schoolClasses)) {
278
			foreach ($schoolClasses as $schoolClass) {
279
				$result[$schoolClass['@key']] = $this->_convertSchoolClass($schoolClass);
280
			}
281
		}
282
283
		return $result;
284
	}
285
286
/**
287
 * Convert student element in extracted Edexml data to normalized data
288
 *
289
 * @param array $student Student element from extracted Edexml data
290
 * @return array Normalized data
291
 */
292
	protected function _convertStudent($student) {
293
		$result = [
294
			'key' => null,
295
			'date_of_birth' => null,
296
			'gender' => null,
297
			'grade' => null,
298
			'SchoolClass' => []
299
		];
300
301
		if (!empty($student['@key'])) {
302
			$result['key'] = $this->_convertKey($student['@key']);
303
		}
304
305
		if (!empty($student['@eckid'])) {
306
			$result['eckid'] = $student['@eckid'];
307
		}
308
309
		$result = array_merge($result, $this->_convertNames($student));
310
		if (!empty($student['geboortedatum'])) {
311
			if (strtotime($student['geboortedatum'])) {
312
				$result['date_of_birth'] = $student['geboortedatum'];
313
			}
314
		}
315
316
		if (!empty($student['geslacht'])) {
317
			switch ($student['geslacht']) {
318
				case 1:
319
					$result['gender'] = 'm';
320
					break;
321
				case 2:
322
					$result['gender'] = 'f';
323
					break;
324
			}
325
		}
326
327
		if (!empty($student['groep']['@key'])) {
328
			$result['SchoolClass'][$student['groep']['@key']] = $this->_schoolClasses[$student['groep']['@key']];
329
			$result['grade'] = $this->_schoolClasses[$student['groep']['@key']]['grade'];
330
		}
331
332
		if (!empty($student['jaargroep'])) {
333
			$result['grade'] = $this->_yearGroupToGradeMapping[$student['jaargroep']];
334
		}
335
336
		return $result;
337
	}
338
339
/**
340
 * Convert teacher element in extracted Edexml data to normalized data
341
 *
342
 * @param array $teacher Teacher element from extracted Edexml data
343
 * @return array Normalized data
344
 */
345
	protected function _convertTeacher($teacher) {
346
		$result = [
347
			'key' => null,
348
			'date_of_birth' => null,
349
			'gender' => null,
350
			'grade' => null,
351
			'email_address' => null,
352
			'SchoolClass' => []
353
		];
354
355
		if (!empty($teacher['@key'])) {
356
			$result['key'] = $this->_convertKey($teacher['@key']);
357
		}
358
359
		if (!empty($teacher['@eckid'])) {
360
			$result['eckid'] = $teacher['@eckid'];
361
		}
362
363
		$result = array_merge($result, $this->_convertNames($teacher));
364
365
		if (!empty($teacher['emailadres'])) {
366
			$result['email_address'] = $teacher['emailadres'];
367
		}
368
369
		if (!empty($teacher['groepen']['groep'])) {
370
			if (!Hash::numeric(array_keys($teacher['groepen']['groep']))) {
371
				$teacher['groepen']['groep'] = [$teacher['groepen']['groep']];
372
			}
373
374
			foreach ($teacher['groepen']['groep'] as $groep) {
375
				$result['SchoolClass'][$groep['@key']] = $this->_schoolClasses[$groep['@key']];
376
			}
377
		}
378
379
		return $result;
380
	}
381
382
/**
383
 * Convert extracted Edexml data to normalized data
384
 *
385
 * @param array $data Extracted Edexml data
386
 * @return array Normalized data
387
 */
388
	public function convert($data) {
389
		$result = [];
390
391
		$result['school'] = $this->_convertSchool($data['EDEX']['school']);
392
393
		if (!empty($data['EDEX']['groepen']['groep'])) {
394
			if (!Hash::numeric(array_keys($data['EDEX']['groepen']['groep']))) {
395
				$data['EDEX']['groepen']['groep'] = [$data['EDEX']['groepen']['groep']];
396
			}
397
398
			$this->_schoolClasses = $this->_convertSchoolClasses($data['EDEX']['groepen']['groep']);
399
			$result['SchoolClass'] = $this->_schoolClasses;
400
		}
401
402
		if (!empty($data['EDEX']['leerlingen']['leerling'])) {
403
			if (!Hash::numeric(array_keys($data['EDEX']['leerlingen']['leerling']))) {
404
				$data['EDEX']['leerlingen']['leerling'] = [$data['EDEX']['leerlingen']['leerling']];
405
			}
406
			foreach ($data['EDEX']['leerlingen']['leerling'] as $i => $student) {
407
				$result['Student'][$i] = $this->_convertStudent($student);
408
			}
409
		}
410
411
		if (!empty($data['EDEX']['leerkrachten']['leerkracht'])) {
412
			if (!Hash::numeric(array_keys($data['EDEX']['leerkrachten']['leerkracht']))) {
413
				$data['EDEX']['leerkrachten']['leerkracht'] = [$data['EDEX']['leerkrachten']['leerkracht']];
414
			}
415
416
			foreach ($data['EDEX']['leerkrachten']['leerkracht'] as $i => $teacher) {
417
				$result['Teacher'][$i] = $this->_convertTeacher($teacher);
418
			}
419
		}
420
421
		return $result;
422
	}
423
}
424