Skip to content

Commit 99a394b

Browse files
committed
Update models generator (preserve existing model members)
1 parent d089b24 commit 99a394b

File tree

4 files changed

+384
-82
lines changed

4 files changed

+384
-82
lines changed
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
<?php
2+
3+
4+
namespace Ubiquity\orm\comparator;
5+
6+
7+
use Ubiquity\orm\creator\Member;
8+
use Ubiquity\orm\creator\Model;
9+
use Ubiquity\utils\base\UIntrospection;
10+
11+
/**
12+
* Merge a model class with an existing model class.
13+
* Ubiquity\orm\comparator$ClassMerger
14+
* This class is part of Ubiquity
15+
*
16+
* @author jcheron <[email protected]>
17+
* @version 1.0.0
18+
* @category ubiquity.dev
19+
*
20+
*/
21+
class ClassMerger {
22+
protected $class;
23+
protected $classCode;
24+
protected Model $model;
25+
protected $merged;
26+
protected $extCode;
27+
28+
public function __construct(string $class,Model $model){
29+
$this->class=$class;
30+
$this->classCode=UIntrospection::getClassCode($class);
31+
$this->model=$model;
32+
$this->merged=false;
33+
$this->extCode='';
34+
}
35+
36+
public function merge(){
37+
if(!$this->merged) {
38+
$r = new \ReflectionClass($this->class);
39+
$properties = $r->getProperties();
40+
$newMembers = $this->model->getMembers();
41+
$annotsEngine = $this->model->getAnnotsEngine();
42+
foreach ($properties as $property) {
43+
$propName = $property->getName();
44+
$propComparator = new MemberComparator($this->class, $propName);
45+
if (isset($newMembers[$propName])) {
46+
$newMember = $newMembers[$propName];
47+
$propComparator->compareTo($newMember);
48+
$preservedAttributes = $propComparator->compareAttributes();
49+
if (\count($preservedAttributes) > 0) {
50+
$newMember->addAnnotations($preservedAttributes);
51+
}
52+
} else {
53+
if ($propComparator->maintain()) {
54+
$m = new Member($this->model, $annotsEngine, $propName);
55+
$m->setTransient();
56+
$this->model->addMember($m);
57+
}
58+
}
59+
}
60+
$actualMethods=$r->getMethods();
61+
$newMethods=$this->model->getMethods();
62+
foreach ($actualMethods as $reflectionMethod){
63+
$code='';
64+
$methodName=$reflectionMethod->getName();
65+
if(\array_search($methodName,$newMethods)===false){
66+
$code=UIntrospection::getMethodCode($reflectionMethod,$this->classCode);
67+
$annotations=$reflectionMethod->getAttributes();
68+
if(\count($annotations)>0) {
69+
$code = $this->model->getAnnotsEngine()->getAnnotationsStr($annotations).$code;
70+
}
71+
}
72+
$this->extCode.=$code;
73+
}
74+
$this->merged = true;
75+
}
76+
}
77+
78+
private function removeBlank($str){
79+
return \str_replace ([' ',PHP_EOL,"\t"], '', $str);
80+
}
81+
82+
public function getMethodCode($methodName,$newCode){
83+
if(\method_exists($this->class,$methodName)){
84+
$r=new \ReflectionMethod($this->class.'::'.$methodName);
85+
$oldCode=UIntrospection::getMethodCode($r,$this->classCode);
86+
$annotations=$r->getAttributes();
87+
if(\count($annotations)>0) {
88+
$oldCode = $this->model->getAnnotsEngine()->getAnnotationsStr($annotations).$oldCode;
89+
}
90+
if($this->removeBlank($oldCode)!==$this->removeBlank($newCode)){
91+
return $oldCode;
92+
}
93+
}
94+
return $newCode;
95+
}
96+
97+
/**
98+
* @return string
99+
*/
100+
public function getExtCode(): string {
101+
return $this->extCode;
102+
}
103+
104+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
<?php
2+
3+
namespace Ubiquity\orm\comparator;
4+
5+
6+
use Ubiquity\cache\CacheManager;
7+
use Ubiquity\orm\creator\Member;
8+
9+
/**
10+
* Compare model members with an existing model.
11+
* Ubiquity\orm\comparatorMemberComparator
12+
* This class is part of Ubiquity
13+
*
14+
* @author jcheron <[email protected]>
15+
* @version 1.0.0
16+
* @category ubiquity.dev
17+
*
18+
*/
19+
class MemberComparator {
20+
protected $member;
21+
protected $class;
22+
protected Member $newMember;
23+
24+
public function __construct(string $class,string $member){
25+
$this->class=$class;
26+
$this->member=$member;
27+
}
28+
29+
public function compareTo(Member $member){
30+
$this->newMember=$member;
31+
}
32+
33+
34+
protected function getAnnotations(string $class,string $member): array {
35+
return CacheManager::getAnnotationsEngineInstance()->getAnnotsOfProperty($class,$member);
36+
}
37+
38+
public function compareAttributes(){
39+
$myAnnots=$this->getAnnotations($this->class,$this->member);
40+
$otherAnnots=$this->newMember->getAnnotations();
41+
$result=[];
42+
foreach ($myAnnots as $myAnnot){
43+
$index=$this->indexOfAnnotation($myAnnot,$otherAnnots);
44+
if($index===-1){
45+
$result[]=$myAnnot;
46+
}
47+
}
48+
return $result;
49+
}
50+
51+
protected function indexOfAnnotation($annotation,array $annots){
52+
$contains=-1;
53+
foreach ($annots as $index=>$annot){
54+
if($annot->isSameAs($annotation)){
55+
return $index;
56+
}
57+
}
58+
return $contains;
59+
}
60+
61+
public function maintain(){
62+
return \count(CacheManager::getAnnotationsEngineInstance()->getAnnotsOfProperty($this->class,$this->member,'transient'))>0;
63+
}
64+
}

src/Ubiquity/orm/creator/Member.php

Lines changed: 43 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
* This class is part of Ubiquity
1212
*
1313
* @author jcheron <[email protected]>
14-
* @version 1.0.3
14+
* @version 1.0.4
1515
* @category ubiquity.dev
1616
*
1717
*/
@@ -20,6 +20,8 @@ class Member {
2020
private $name;
2121

2222
private $primary;
23+
24+
private $transient;
2325

2426
private $manyToOne;
2527

@@ -40,13 +42,14 @@ public function __construct($container,$annotsEngine,$name, $access = 'private')
4042
$this->name = $name;
4143
$this->annotations = [];
4244
$this->primary = false;
45+
$this->transient=false;
4346
$this->manyToOne = false;
4447
$this->access = $access;
4548
}
4649

4750
public function __toString() {
4851
$annotationsStr = '';
49-
if (sizeof($this->annotations) > 0) {
52+
if (\count($this->annotations) > 0) {
5053
$annotationsStr = "\n".$this->annotsEngine->getAnnotationsStr($this->annotations);
5154
}
5255
return $annotationsStr . "\n\t{$this->access} $" . $this->name . ";\n";
@@ -59,6 +62,13 @@ public function setPrimary() {
5962
}
6063
}
6164

65+
public function setTransient() {
66+
if ($this->transient === false) {
67+
$this->annotations[] = $this->annotsEngine->getAnnotation($this->container,'transient');
68+
$this->transient = true;
69+
}
70+
}
71+
6272
public function setDbType($infos) {
6373
$annot = $this->annotsEngine->getAnnotation($this->container,'column',['name'=>$this->name,'dbType'=>$infos['Type'],'nullable'=>(\strtolower($infos['Nullable']) === 'yes')]);
6474
$this->annotations['column'] = $annot;
@@ -162,30 +172,46 @@ public function isAutoinc(){
162172
}
163173

164174
public function getGetter() {
165-
$result = "\n\tpublic function get" . \ucfirst($this->name) . "(){\n";
175+
$result = "\n\tpublic function " . $this->getGetterName() . "(){\n";
166176
$result .= "\t\t" . 'return $this->' . $this->name . ";\n";
167177
$result .= "\t}\n";
168178
return $result;
169179
}
170180

181+
public function getGetterName(){
182+
return 'get' . \ucfirst($this->name);
183+
}
184+
171185
public function getSetter() {
172-
$result = "\n\tpublic function set" . \ucfirst($this->name) . '($' . $this->name . "){\n";
186+
$result = "\n\tpublic function " . $this->getSetterName() . '($' . $this->name . "){\n";
173187
$result .= "\t\t" . '$this->' . $this->name . '=$' . $this->name . ";\n";
174188
$result .= "\t}\n";
175189
return $result;
176190
}
177191

192+
public function getSetterName(){
193+
return 'set' . \ucfirst($this->name);
194+
}
195+
178196
public function getAddInManyMember() {
179197
$name = $this->name;
180198
if (\substr($name, - 1) === 's') {
181199
$name = \substr($name, 0, - 1);
182200
}
183-
$result = "\n\t public function add" . \ucfirst($name) . '($' . $name . "){\n";
201+
$result = "\n\t public function " . $this->getInManyMemberName() . '($' . $name . "){\n";
184202
$result .= "\t\t" . '$this->' . $this->name . '[]=$' . $name . ";\n";
185203
$result .= "\t}\n";
186204
return $result;
187205
}
188206

207+
public function getInManyMemberName(){
208+
$name = $this->name;
209+
if (\substr($name, - 1) === 's') {
210+
$name = \substr($name, 0, - 1);
211+
}
212+
return 'add'.\ucfirst($name);
213+
}
214+
189215
public function hasAnnotations() {
190216
return \count($this->annotations) > 1;
191217
}
@@ -222,4 +248,16 @@ public function addValidators() {
222248
public function getAnnotations() {
223249
return $this->annotations;
224250
}
251+
252+
public function getMethods(){
253+
$r=[$this->getGetterName(),$this->getSetterName()];
254+
if($this->isMany()){
255+
$r[]=$this->getInManyMemberName();
256+
}
257+
return $r;
258+
}
259+
260+
public function addAnnotations(array $annotations){
261+
$this->annotations=\array_merge($this->annotations,$annotations);
262+
}
225263
}

0 commit comments

Comments
 (0)