Passed
Push — master ( 83996b...17a193 )
by Jean-Christophe
09:22
created

ModelParser::parse()   B

Complexity

Conditions 8
Paths 34

Size

Total Lines 34
Code Lines 30

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 30
CRAP Score 8.0021

Importance

Changes 0
Metric Value
eloc 30
dl 0
loc 34
ccs 30
cts 31
cp 0.9677
rs 8.1954
c 0
b 0
f 0
cc 8
nc 34
nop 1
crap 8.0021
1
<?php
2
namespace Ubiquity\orm\parser;
3
4
use Ubiquity\utils\base\UArray;
5
use Ubiquity\contents\transformation\TransformersManager;
6
use Ubiquity\exceptions\TransformerException;
7
8
/**
9
 * Parse model annotation for cache generation.
10
 * Ubiquity\orm\parser$ModelParser
11
 * This class is part of Ubiquity
12
 *
13
 * @author jcheron <[email protected]>
14
 * @version 1.0.1
15
 *         
16
 */
17
class ModelParser {
18
19
	protected $global;
20
21
	protected $primaryKeys;
22
23
	protected $manytoOneMembers;
24
25
	protected $oneToManyMembers;
26
27
	protected $manyToManyMembers;
28
29
	protected $joinColumnMembers;
30
31
	protected $joinTableMembers;
32
33
	protected $nullableMembers = [];
34
35
	protected $notSerializableMembers = [];
36
37
	protected $fieldNames;
38
39
	protected $fieldTypes = [];
40
41
	protected $transformers = [];
42
43
	protected $accessors = [];
44
45
	protected $yuml;
46
47 18
	public function parse($modelClass) {
48 18
		$instance = new $modelClass();
49 18
		$this->primaryKeys = Reflexion::getKeyFields($instance);
50 18
		$this->oneToManyMembers = Reflexion::getMembersAnnotationWithAnnotation($modelClass, "@oneToMany");
51 18
		$this->manytoOneMembers = Reflexion::getMembersNameWithAnnotation($modelClass, "@manyToOne");
52 18
		$this->manyToManyMembers = Reflexion::getMembersAnnotationWithAnnotation($modelClass, "@manyToMany");
53 18
		$this->joinColumnMembers = Reflexion::getMembersAnnotationWithAnnotation($modelClass, "@joinColumn");
54 18
		$this->joinTableMembers = Reflexion::getMembersAnnotationWithAnnotation($modelClass, "@joinTable");
55 18
		$this->transformers = Reflexion::getMembersAnnotationWithAnnotation($modelClass, "@transformer");
56 18
		$yuml = Reflexion::getAnnotationClass($modelClass, "@yuml");
57 18
		if (\sizeof($yuml) > 0)
58
			$this->yuml = $yuml[0];
59 18
		$properties = Reflexion::getProperties($instance);
60 18
		foreach ($properties as $property) {
61 18
			$propName = $property->getName();
62 18
			$fieldName = Reflexion::getFieldName($modelClass, $propName);
63 18
			$this->fieldNames[$propName] = $fieldName;
64 18
			$nullable = Reflexion::isNullable($modelClass, $propName);
65 18
			$serializable = Reflexion::isSerializable($modelClass, $propName);
66 18
			if ($nullable)
67 17
				$this->nullableMembers[] = $propName;
68 18
			if (! $serializable)
69 18
				$this->notSerializableMembers[] = $propName;
70 18
			$type = Reflexion::getDbType($modelClass, $propName);
71 18
			if ($type === false)
72 17
				$type = "mixed";
73 18
			$this->fieldTypes[$propName] = $type;
74 18
			$accesseur = "set" . ucfirst($propName);
75 18
			if (! isset($this->accessors[$fieldName]) && method_exists($modelClass, $accesseur)) {
76 18
				$this->accessors[$fieldName] = $accesseur;
77
			}
78
		}
79
80 18
		$this->global["#tableName"] = Reflexion::getTableName($modelClass);
81 18
	}
82
83 18
	public function asArray() {
84 18
		$result = $this->global;
85 18
		$result["#primaryKeys"] = $this->primaryKeys;
86 18
		$result["#manyToOne"] = $this->manytoOneMembers;
87 18
		$result["#fieldNames"] = $this->fieldNames;
88 18
		$result["#fieldTypes"] = $this->fieldTypes;
89 18
		$result["#nullable"] = $this->nullableMembers;
90 18
		$result["#notSerializable"] = $this->notSerializableMembers;
91 18
		$result["#transformers"] = [];
92 18
		$result["#accessors"] = $this->accessors;
93 18
		if (isset($this->yuml))
94
			$result["#yuml"] = $this->yuml->getPropertiesAndValues();
95 18
		foreach ($this->oneToManyMembers as $member => $annotation) {
96 17
			$result["#oneToMany"][$member] = $annotation->getPropertiesAndValues();
97
		}
98 18
		foreach ($this->manyToManyMembers as $member => $annotation) {
99 17
			$result["#manyToMany"][$member] = $annotation->getPropertiesAndValues();
100
		}
101
102 18
		foreach ($this->joinTableMembers as $member => $annotation) {
103 17
			$result["#joinTable"][$member] = $annotation->getPropertiesAndValues();
104
		}
105
106 18
		if (class_exists("Ubiquity\\contents\\transformation\\TransformersManager")) {
107 18
			TransformersManager::start();
108 18
			foreach ($this->transformers as $member => $annotation) {
109
				$goodTransformer = false;
110
				if (array_search($member, $this->notSerializableMembers, false) !== false) {
111
					throw new TransformerException(sprintf('%s member is not serializable and does not supports transformers!', $member));
112
				}
113
				$trans = TransformersManager::getTransformerClass($annotation->name);
114
				if ($trans == null) {
115
					throw new TransformerException(sprintf('%s value is not a declared transformer.', $annotation->name));
116
				} else {
117
					foreach (TransformersManager::TRANSFORMER_TYPES as $transType => $transInterface) {
118
						if (is_subclass_of($trans, $transInterface, true)) {
119
							$goodTransformer = true;
120
							$result["#transformers"][$transType][$member] = $trans;
121
						}
122
					}
123
					if (! $goodTransformer) {
124
						throw new TransformerException(sprintf('%s does not implements %s', $trans, 'TransformerInterfaces'));
125
					}
126
				}
127
			}
128
		}
129
130 18
		foreach ($this->joinColumnMembers as $member => $annotation) {
131 18
			$result["#joinColumn"][$member] = $annotation->getPropertiesAndValues();
132 18
			$result["#invertedJoinColumn"][$annotation->name] = [
133 18
				"member" => $member,
134 18
				"className" => $annotation->className
135
			];
136
		}
137 18
		return $result;
138
	}
139
140 6
	public function __toString() {
141 6
		return "return " . UArray::asPhpArray($this->asArray(), "array") . ";";
142
	}
143
}
144