Ubiquity 2.5.2
php rapid development framework
Loading...
Searching...
No Matches
ModelsCreator.php
Go to the documentation of this file.
1<?php
3
8
19abstract class ModelsCreator {
20
21 private $silent = false;
22
23 protected $config;
24
25 protected $tables = array();
26
27 protected $classes = array();
28
29 protected $memberAccess;
30
31 abstract protected function getTablesName();
32
33 abstract protected function getFieldsInfos($tableName);
34
35 abstract protected function getPrimaryKeys($tableName);
36
37 abstract protected function getForeignKeys($tableName, $pkName, $dbName = null);
38
39 protected function init(array $config, string $offset = 'default') {
40 $this->config = DAO::getDbOffset($config, $offset);
41 }
42
43 public function create(array $config, bool $initCache = true, ?string $singleTable = null, string $offset = 'default', string $memberAccess = 'private') {
44 \ob_start();
45 $engine = CacheManager::getAnnotationsEngineInstance();
46 $this->init($config, $offset);
47 $this->memberAccess = $memberAccess;
48 $dirPostfix = '';
49 $nsPostfix = '';
50 if ($offset !== 'default') {
51 $dirPostfix = \DS . $offset;
52 $nsPostfix = $offset;
53 }
54 $modelsDir = Startup::getModelsCompletePath() . $dirPostfix;
55 if (UFileSystem::safeMkdir($modelsDir)) {
56 $this->tables = $this->getTablesName();
57 CacheManager::checkCache($config);
58
59 foreach ($this->tables as $table) {
60 $class = new Model($engine, $table, Startup::getNS('models') . $nsPostfix, $memberAccess);
61 $class->setDatabase($offset);
62
63 $fieldsInfos = $this->getFieldsInfos($table);
64 $class->setSimpleMembers(\array_keys($fieldsInfos));
65 $keys = $this->getPrimaryKeys($table);
66 foreach ($fieldsInfos as $field => $info) {
67 $member = new Member($class, $engine, $field, $memberAccess);
68 if (\in_array($field, $keys)) {
69 $member->setPrimary();
70 }
71 $member->setDbType($info);
72 $member->addValidators();
73 $member->setTransformer();
74 $class->addMember($member);
75 }
76 $class->addMainAnnots();
77 $this->classes[$table] = $class;
78 }
79 $this->createRelations();
80
81 if (isset($singleTable)) {
82 $this->createOneClass($singleTable, $modelsDir);
83 } else {
84 foreach ($this->classes as $table => $class) {
85 $name = $class->getSimpleName();
86 echo "Creating the {$name} class\n";
87 $classContent = $class->__toString();
88 $this->writeFile($modelsDir . \DS . $name . '.php', $classContent);
89 }
90 }
91 if ($initCache === true) {
92 CacheManager::initCache($config, 'models', $this->silent);
93 }
94 }
95 $r = \ob_get_clean();
96 if ($this->silent) {
97 return $r;
98 }
99 echo $r;
100 }
101
102 protected function createOneClass(string $singleTable, string $modelsDir) {
103 if (isset($this->classes[$singleTable])) {
104 $class = $this->classes[$singleTable];
105 echo "Creating the {$class->getName()} class\n";
106 $classContent = $class->__toString();
107 $this->writeFile($modelsDir . \DS . $class->getSimpleName() . '.php', $classContent);
108 } else {
109 echo "The {$singleTable} table does not exist in the database\n";
110 }
111 }
112
113 protected function createRelations() {
114 foreach ($this->classes as $table => $class) {
115 $keys = $this->getPrimaryKeys($table);
116 foreach ($keys as $key) {
117 $fks = $this->getForeignKeys($table, $key, $this->config['dbName'] ?? '');
118 foreach ($fks as $fk) {
119 $field = \lcfirst($table);
120 $fkTable = $fk['TABLE_NAME'];
121 $this->classes[$table]->addOneToMany(\lcfirst($fkTable) . 's', \lcfirst($table), $this->classes[$fkTable]->getName(), $this->getAlternateName($fk['COLUMN_NAME'], $fk['REFERENCED_COLUMN_NAME'] ?? $field) . 's');
122 $this->classes[$fkTable]->addManyToOne($field, \lcfirst($fk['COLUMN_NAME']), $class->getName(), $this->getAlternateName($fk['COLUMN_NAME'], $fk['REFERENCED_COLUMN_NAME'] ?? $field));
123 }
124 }
125 }
126 $this->createManyToMany();
127 }
128
129 protected function getAlternateName(string $fkName, string $pkName): string {
130 $alter = $fkName;
131 $pkName = \ucfirst($pkName);
132 if (\substr($fkName, 0, \strlen($pkName)) == $pkName) {
133 $alter = \substr($fkName, \strlen($pkName));
134 }
135 $needle_position = \strlen($pkName) * - 1;
136
137 if (\substr($alter, $needle_position) == $pkName) {
138 $alter = \substr($alter, 0, $needle_position);
139 }
140 $alter = \trim($alter, '_');
141 return \lcfirst($alter);
142 }
143
144 protected function getTableName(string $classname): string {
145 foreach ($this->classes as $table => $class) {
146 if ($class->getName() === $classname) {
147 return $table;
148 }
149 }
150 $posSlash = strrpos($classname, '\\');
151 $tablename = substr($classname, $posSlash + 1);
152 return \lcfirst($tablename);
153 }
154
155 protected function createManyToMany() {
156 foreach ($this->classes as $table => $class) {
157 if ($class->isAssociation() === true) {
158 $members = $class->getManyToOneMembers();
159 if (\count($members) == 2) {
160 $manyToOne1 = $members[0]->getManyToOne();
161 $manyToOne2 = $members[1]->getManyToOne();
162 $table1 = $this->getTableName($manyToOne1->className);
163 $table2 = $this->getTableName($manyToOne2->className);
164 $class1 = $this->classes[$table1];
165 $class2 = $this->classes[$table2];
166 $reflexive = ($class1 === $class2);
167 if ($reflexive) {
168 $table1Member = $table2Member = $table . 's';
169 $altName1 = $this->getAlternateName($manyToOne2->name, \current($this->getPrimaryKeys($table1))) . 's';
170 } else {
171 $table1Member = \lcfirst($table1) . 's';
172 $table2Member = \lcfirst($table2) . 's';
173 $altName1 = $altName2 = $table . 's';
174 }
175 $joinTable1 = $this->getJoinTableArray($class1, $manyToOne1);
176 $joinTable2 = $this->getJoinTableArray($class2, $manyToOne2);
177 $class1->removeOneToManyMemberByClassAssociation($class->getName());
178 $class1->addManyToMany($table2Member, $manyToOne2->className, $table1Member, $table, $joinTable1, $joinTable2, $altName1);
179 if (! $reflexive) {
180 $class2->removeOneToManyMemberByClassAssociation($class->getName());
181 $class2->addManyToMany($table1Member, $manyToOne1->className, $table2Member, $table, $joinTable2, $joinTable1, $altName2);
182 }
183 unset($this->classes[$table]);
184 }
185 }
186 }
187 }
188
189 protected function getJoinTableArray(Model $class, object $joinColumn) {
190 $pk = $class->getPrimaryKey();
191 $fk = $joinColumn->name;
192 $dFk = $class->getDefaultFk();
193 if ($fk !== $dFk) {
194 if ($pk !== null && $fk !== null)
195 return [
196 'name' => $fk,
197 'referencedColumnName' => $pk->getName()
198 ];
199 }
200 return [];
201 }
202
203 protected function writeFile(string $filename, string $data): int {
204 return \file_put_contents($filename, $data);
205 }
206
211 public function setSilent(bool $silent): void {
212 $this->silent = $silent;
213 }
214}
Manager for caches (Router, Rest, models).
Starts the framework.
Definition Startup.php:19
Gateway class between database and object model.
Definition DAO.php:33
static getDbOffset(&$config, $offset=null)
Definition DAO.php:252
writeFile(string $filename, string $data)
createOneClass(string $singleTable, string $modelsDir)
init(array $config, string $offset='default')
getForeignKeys($tableName, $pkName, $dbName=null)
getJoinTableArray(Model $class, object $joinColumn)
getAlternateName(string $fkName, string $pkName)
create(array $config, bool $initCache=true, ?string $singleTable=null, string $offset='default', string $memberAccess='private')
File system utilities Ubiquity\utils\base$UFileSystem This class is part of Ubiquity.