Completed
Push — master ( 499e80...f97bb0 )
by Jean-Christophe
01:49
created

ModelsCreator::create()   C

Complexity

Conditions 8
Paths 17

Size

Total Lines 36
Code Lines 27

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 36
rs 5.3846
c 0
b 0
f 0
cc 8
eloc 27
nc 17
nop 3
1
<?php
2
namespace Ubiquity\orm\creator;
3
4
use Ubiquity\orm\creator\Model;
5
use Ubiquity\orm\creator\Member;
6
use Ubiquity\annotations\JoinColumnAnnotation;
7
use Ubiquity\cache\CacheManager;
8
use Ubiquity\controllers\Startup;
9
use Ubiquity\utils\FsUtils;
10
11
12
abstract class ModelsCreator {
13
	protected $config;
14
	protected $tables=array();
15
	protected $classes=array();
16
17
	protected function init($config){
18
		$this->config=$config["database"];
19
	}
20
21
	public function create($config,$initCache=true,$singleTable=null){
22
		$this->init($config);
23
		$modelsDir=Startup::getModelsCompletePath();
24
		if(FsUtils::safeMkdir($modelsDir)){
25
			$this->tables=$this->getTablesName();
26
			CacheManager::checkCache($config);
27
28
			foreach ($this->tables as $table){
29
				$class=new Model($table,$config["mvcNS"]["models"]);
30
				$fieldsInfos=$this->getFieldsInfos($table);
31
				$keys=$this->getPrimaryKeys($table);
32
				foreach ($fieldsInfos as $field=>$info){
33
					$member=new Member($field);
34
					if(in_array($field, $keys)){
35
						$member->setPrimary();
36
					}
37
					$member->setDbType($info);
38
					$class->addMember($member);
39
				}
40
				$this->classes[$table]=$class;
41
			}
42
			$this->createRelations();
43
			if(isset($singleTable)){
44
				$this->createOneClass($singleTable,$modelsDir);
45
			}else{
46
				foreach ($this->classes as $table=>$class){
47
					$name=$class->getSimpleName();
48
					echo "Creating the {$name} class\n";
49
					$this->writeFile($modelsDir.DS.$name.".php", $class);
50
				}
51
			}
52
			if($initCache===true){
53
				CacheManager::initCache($config,"models");
54
			}
55
		}
56
	}
57
58
	protected function createOneClass($singleTable,$modelsDir){
59
		if(isset($this->classes[$singleTable])){
60
			$class=$this->classes[$singleTable];
61
			echo "Creating the {$class->getName()} class\n";
62
			$this->writeFile($modelsDir.DS.$singleTable.".php", $class);
63
		}else{
64
			echo "The {$singleTable} table does not exist in the database\n";
65
		}
66
	}
67
68
	protected function createRelations(){
69
		foreach ($this->classes as $table=>$class){
70
			$keys=$this->getPrimaryKeys($table);
71
			foreach ($keys as $key){
72
				$fks=$this->getForeignKeys($table, $key);
73
				foreach ($fks as $fk){
74
					$field=strtolower($table);
75
					$fkTable=$fk["TABLE_NAME"];
76
					$this->classes[$table]->addOneToMany($fkTable."s",$table, $this->classes[$fkTable]->getName());
77
					$this->classes[$fkTable]->addManyToOne($field, $fk["COLUMN_NAME"], $class->getName());
78
				}
79
			}
80
		}
81
		$this->createManyToMany();
82
	}
83
84
	protected function getTableName($classname){
85
		foreach ($this->classes as $table=>$class){
86
			if($class->getName()===$classname)
87
				return $table;
88
		}
89
		$posSlash=strrpos($classname, '\\');
90
		$tablename=substr($classname,  $posSlash+ 1);
91
		return lcfirst($tablename);
92
	}
93
94
	protected function createManyToMany(){
95
		foreach ($this->classes as $table=>$class){
96
			if($class->isAssociation()===true){
97
				$members=$class->getManyToOneMembers();
98
				if(sizeof($members)==2){
99
					$manyToOne1=$members[0]->getManyToOne();
100
					$manyToOne2=$members[1]->getManyToOne();
101
					$table1=$this->getTableName($manyToOne1->className);
102
					$table2=$this->getTableName($manyToOne2->className);
103
					$class1=$this->classes[$table1];
104
					$class2=$this->classes[$table2];
105
					$tableMember=\lcfirst($table)."s";
106
					$table1Member=\lcfirst($table1)."s";
107
					$table2Member=\lcfirst($table2)."s";
108
					$joinTable1=$this->getJoinTableArray($class1, $manyToOne1);
109
					$joinTable2=$this->getJoinTableArray($class2, $manyToOne2);
110
					$class1->addManyToMany($table2Member, $manyToOne2->className, $table1Member, $table,$joinTable1,$joinTable2);
111
					$class1->removeMember($tableMember);
112
113
					$class2->addManyToMany($table1Member, $manyToOne1->className, $table2Member, $table,$joinTable2,$joinTable1);
114
					$class2->removeMember($tableMember);
115
					unset($this->classes[$table]);
116
				}else{
117
					return;
118
				}
119
			}
120
		}
121
	}
122
123
	protected function getJoinTableArray(Model $class,JoinColumnAnnotation $joinColumn){
124
		$pk=$class->getPrimaryKey();
125
		$fk=$joinColumn->name;
126
		$dFk=$class->getDefaultFk();
127
		if($fk!==$dFk){
128
			if($pk!==null && $fk!==null && $pk!==null)
129
				return ["name"=>$fk, "referencedColumnName"=>$pk];
130
		}
131
		return [];
132
	}
133
134
	abstract protected function getTablesName();
135
136
	abstract protected function getFieldsInfos($tableName);
137
138
	abstract protected function getPrimaryKeys($tableName);
139
140
	protected function writeFile($filename,$data){
141
		return file_put_contents($filename,$data);
142
	}
143
}
144