18class Model
extends HasUsesTrait {
20 private $simpleMembers;
32 private $memberAccess;
34 private $annotsEngine;
40 public function __construct($annotsEngine, $name, $namespace =
'models', $memberAccess =
'private') {
41 $this->annotsEngine = $annotsEngine;
43 $this->name = \ucfirst($name);
44 $this->members = array();
45 $this->
namespace = $namespace;
46 $this->memberAccess = $memberAccess;
54 public function getMembers(): array {
55 return $this->members;
58 public function getMethods() {
62 if ($this->hasConstructor()) {
63 $methods[] =
'__construct';
65 foreach ($this->members as $member) {
66 $methods = \array_merge($methods, $member->getMethods());
71 private function hasConstructor(): bool {
72 foreach ($this->members as $member) {
73 if ($member->isMany()) {
84 public function getAnnotsEngine() {
85 return $this->annotsEngine;
88 public function addManyToOne($member, $name, $className, $alternateName) {
89 $this->checkForUniqName($member, $alternateName);
91 if (\array_key_exists($member, $this->members) ===
false) {
92 $this->addMember(
new Member($this, $this->annotsEngine, $member, $this->memberAccess));
93 if (isset($this->members[$name])) {
94 $nullable = $this->members[$name]->isNullable();
95 $this->removeMember($name);
98 $this->members[$member]->addManyToOne($name, $className, $nullable);
101 private function checkForUniqName(&$member, $alternateName) {
102 if (isset($this->members[$member]) && \array_search($member, $this->simpleMembers) ===
false) {
103 if ($alternateName !=
null) {
104 $this->checkForUniqName($alternateName,
null);
105 $member = $alternateName;
107 $member = $this->generateUniqName($member);
112 private function generateUniqName($member) {
115 $name = $member . $i;
117 }
while (isset($this->members[$name]));
121 public function addMember(Member $member) {
122 $this->members[$member->getName()] = $member;
126 public function removeMember($memberName) {
127 if (isset($this->members[$memberName]) && $this->members[$memberName]->isPrimary() ===
false)
128 unset($this->members[$memberName]);
131 public function removeOneToManyMemberByClassAssociation($className) {
133 foreach ($this->members as $name => $member) {
134 $annotations = $member->getAnnotations();
135 foreach ($annotations as $annotation) {
136 if ($this->annotsEngine->is(
'oneToMany', $annotation)) {
137 if ($annotation->className === $className) {
144 foreach ($toDelete as $name) {
145 unset($this->members[$name]);
149 public function addOneToMany($member, $mappedBy, $className, $alternateName) {
150 $this->checkForUniqName($member, $alternateName);
151 if (\array_key_exists($member, $this->members) ===
false) {
152 $this->addMember(
new Member($this, $this->annotsEngine, $member, $this->memberAccess));
154 $this->members[$member]->addOneToMany($mappedBy, $className);
157 public function addManyToMany($member, $targetEntity, $inversedBy, $joinTable, $joinColumns = [], $inverseJoinColumns = [], $alternateName =
null) {
158 $this->checkForUniqName($member, $alternateName);
159 if (\array_key_exists($member, $this->members) ===
false) {
160 $this->addMember(
new Member($this, $this->annotsEngine, $member, $this->memberAccess));
162 $this->members[$member]->addManyToMany($targetEntity, $inversedBy, $joinTable, $joinColumns, $inverseJoinColumns);
166 public function addMainAnnots() {
168 if (\class_exists(
'\AllowDynamicProperties')) {
169 $annots[]=
'#[\AllowDynamicProperties()]';
171 if ($this->database !=
null && $this->database !==
'default') {
172 $annots[] = $this->annotsEngine->getAnnotation($this,
'database', [
173 'name' => $this->database
176 if ($this->table !== $this->name) {
177 $annots[] = $this->annotsEngine->getAnnotation($this,
'table', [
178 'name' => $this->table
181 $this->annots = $annots;
184 public function __toString() {
185 $cm = $this->getClassMerger();
187 if ($this->
namespace !==
'' && $this->
namespace !==
null) {
188 $result .=
'namespace ' . \rtrim($this->
namespace,
'\\') .
";\n";
191 if (\count($this->uses) > 0) {
192 $result .=
"\n" . $this->getUsesStr() .
"\n";
195 if (\count($this->annots) > 0) {
196 $result .= $this->annotsEngine->getAnnotationsStr($this->annots,
'') .
"\n";
198 $result .=
'class ' . \ucfirst($this->name) .
'{';
199 $members = $this->members;
200 \array_walk($members,
function ($item) {
203 $result .= \implode(
'', $members) .
"\n";
204 $result .= $this->generateMethods($members, $cm);
210 protected function getClassMerger(): ?ClassMerger {
211 if (\class_exists(
'\\' . $this->getName(), true)) {
212 if ($this->classMerger ==
null) {
213 $this->classMerger =
new ClassMerger($this->getName(), $this);
214 $this->classMerger->merge();
216 return $this->classMerger;
221 public function getName() {
223 if ($this->
namespace !==
'' && $this->
namespace !==
null) {
224 $namespace = \rtrim($this->
namespace,
'\\') .
'\\';
226 return $namespace . $this->name;
235 protected function generateMethods(array $members, ?ClassMerger $classMerger) {
237 if ($classMerger ==
null) {
238 if ($this->hasConstructor()) {
239 $result = $this->getConstructor() . PHP_EOL;
241 foreach ($members as $member) {
242 $result .= $member->getGetter() . PHP_EOL;
243 $result .= $member->getSetter() . PHP_EOL;
244 if ($member->isManyToMany()) {
245 $result .= $member->getAddInManyToManyMember() . PHP_EOL;
247 if ($member->isOneToMany()) {
248 $result .= $member->getAddInOneToManyMember() . PHP_EOL;
251 $result .= $this->getToString();
253 if ($this->hasConstructor()) {
254 $result = $classMerger->getMethodCode(
'__construct', $this->getConstructor()) . PHP_EOL;
256 foreach ($members as $member) {
257 $result .= $classMerger->getMethodCode($member->getGetterName(), $member->getGetter()) . PHP_EOL;
258 $result .= $classMerger->getMethodCode($member->getSetterName(), $member->getSetter()) . PHP_EOL;
259 if ($member->isManyToMany()) {
260 $result .= $classMerger->getMethodCode($member->getInManyToManyMemberName(), $member->getAddInManyToManyMember()) . PHP_EOL;
262 if ($member->isOneToMany()) {
263 $result .= $classMerger->getMethodCode($member->getInOneToManyMemberName(), $member->getAddInOneToManyMember()) . PHP_EOL;
266 $result .= $classMerger->getMethodCode(
'__toString', $this->getToString()) . PHP_EOL;
267 $result .= $classMerger->getExtCode();
272 public function getConstructor() {
274 foreach ($this->members as $member) {
275 if ($member->isMany()) {
276 $initializes[] =
"\t\t\$this->" . $member->getName() .
' = [];';
279 if (\count($initializes) > 0) {
280 $corps = \implode(PHP_EOL, $initializes);
281 $result =
"\n\t public function __construct(){\n";
282 $result .=
"$corps\n";
289 public function getToString() {
290 $field = $this->getToStringField();
292 $corps =
'($this->' . $field .
"??'no value').''";
293 } elseif (($pkName = $this->getPkName()) !==
null) {
294 $corps =
'$this->' . $pkName .
".''";
296 $corps =
'"' . $this->name .
'@"' .
'.\spl_object_hash($this)';
298 $result =
"\n\t public function __toString(){\n";
299 $result .=
"\t\t" .
'return ' . $corps .
";\n";
304 private function getToStringField() {
306 foreach ($this->members as $member) {
307 if ($member->getDbType() !==
'mixed' && ! $member->isPrimary()) {
308 $memberName = $member->getName();
309 if (! $member->isPassword()) {
310 $result= $memberName;
311 if($member->isNullable()!==
false){
320 public function getPkName() {
321 $pk = $this->getPrimaryKey();
323 return $pk->getName();
328 public function getPrimaryKey() {
329 foreach ($this->members as $member) {
330 if ($member->isPrimary() ===
true) {
337 public function getSimpleName() {
341 public function setDatabase($database) {
342 $this->database = $database;
345 public function isAssociation() {
347 foreach ($this->members as $member) {
348 if ($member->isManyToOne() ===
true || $member->isPrimary() ===
true) {
352 return $count == \count($this->members);
355 public function getDefaultFk() {
356 return 'id' . $this->name;
359 public function getManyToOneMembers() {
361 foreach ($this->members as $member) {
362 if ($member->isManyToOne() ===
true) {
369 public function setSimpleMembers($members) {
370 $this->simpleMembers = $members;
376 public function setTable($table): void {
377 $this->table = $table;
Ubiquity\annotations$AnnotationsInterface This class is part of Ubiquity.