22
33namespace BeyondCode \ErdGenerator ;
44
5+ use Illuminate \Database \Eloquent \Relations \BelongsToMany ;
56use phpDocumentor \GraphViz \Graph ;
67use Illuminate \Support \Collection ;
78use phpDocumentor \GraphViz \Node ;
9+ use \Illuminate \Database \Eloquent \Model as EloquentModel ;
810
911class GraphBuilder
1012{
@@ -28,10 +30,9 @@ public function buildGraph(Collection $models) : Graph
2830 return $ this ->graph ;
2931 }
3032
31- protected function getTableColumnsFromModel (string $ model )
33+ protected function getTableColumnsFromModel (EloquentModel $ model )
3234 {
3335 try {
34- $ model = app ($ model );
3536
3637 $ table = $ model ->getConnection ()->getTablePrefix () . $ model ->getTable ();
3738 $ schema = $ model ->getConnection ()->getDoctrineSchemaManager ($ table );
@@ -51,7 +52,7 @@ protected function getTableColumnsFromModel(string $model)
5152 return [];
5253 }
5354
54- protected function getModelLabel (string $ model , string $ label )
55+ protected function getModelLabel (EloquentModel $ model , string $ label )
5556 {
5657
5758 $ table = '<<table width="100%" height="100%" border="0" margin="0" cellborder="1" cellspacing="0" cellpadding="10"> ' . PHP_EOL ;
@@ -77,7 +78,8 @@ protected function addModelsToGraph(Collection $models)
7778 {
7879 // Add models to graph
7980 $ models ->map (function (Model $ model ) {
80- $ this ->addNodeToGraph ($ model ->getModel (), $ model ->getNodeName (), $ model ->getLabel ());
81+ $ eloquentModel = app ($ model ->getModel ());
82+ $ this ->addNodeToGraph ($ eloquentModel , $ model ->getNodeName (), $ model ->getLabel ());
8183 });
8284
8385 // Create relations
@@ -86,10 +88,10 @@ protected function addModelsToGraph(Collection $models)
8688 });
8789 }
8890
89- protected function addNodeToGraph (string $ className , string $ nodeName , string $ label )
91+ protected function addNodeToGraph (EloquentModel $ eloquentModel , string $ nodeName , string $ label )
9092 {
9193 $ node = Node::create ($ nodeName );
92- $ node ->setLabel ($ this ->getModelLabel ($ className , $ label ));
94+ $ node ->setLabel ($ this ->getModelLabel ($ eloquentModel , $ label ));
9395
9496 foreach (config ('erd-generator.node ' ) as $ key => $ value ) {
9597 $ node ->{"set $ {key}" }($ value );
@@ -103,26 +105,115 @@ protected function addRelationToGraph(Model $model)
103105
104106 $ modelNode = $ this ->graph ->findNode ($ model ->getNodeName ());
105107
108+ /** @var ModelRelation $relation */
106109 foreach ($ model ->getRelations () as $ relation ) {
107110 $ relatedModelNode = $ this ->graph ->findNode ($ relation ->getModelNodeName ());
108111
109112 if ($ relatedModelNode !== null ) {
110- $ edge = Edge::create ($ modelNode , $ relatedModelNode );
111- $ edge ->setFromPort ($ relation ->getLocalKey ());
112- $ edge ->setToPort ($ relation ->getForeignKey ());
113- $ edge ->setLabel (' ' );
114- $ edge ->setXLabel ($ relation ->getType (). PHP_EOL . $ relation ->getName ());
115-
116- foreach (config ('erd-generator.edge ' ) as $ key => $ value ) {
117- $ edge ->{"set $ {key}" }($ value );
118- }
113+ $ this ->connectByRelation ($ model , $ relation , $ modelNode , $ relatedModelNode );
114+ }
115+ }
116+ }
119117
120- foreach (config ('erd-generator.relations. ' . $ relation ->getType (), []) as $ key => $ value ) {
121- $ edge ->{"set $ {key}" }($ value );
122- }
118+ /**
119+ * @param Node $modelNode
120+ * @param Node $relatedModelNode
121+ * @param ModelRelation $relation
122+ */
123+ protected function connectNodes (Node $ modelNode , Node $ relatedModelNode , ModelRelation $ relation ): void
124+ {
125+ $ edge = Edge::create ($ modelNode , $ relatedModelNode );
126+ $ edge ->setFromPort ($ relation ->getLocalKey ());
127+ $ edge ->setToPort ($ relation ->getForeignKey ());
128+ $ edge ->setLabel (' ' );
129+ $ edge ->setXLabel ($ relation ->getType () . PHP_EOL . $ relation ->getName ());
130+
131+ foreach (config ('erd-generator.edge ' ) as $ key => $ value ) {
132+ $ edge ->{"set $ {key}" }($ value );
133+ }
123134
124- $ this -> graph -> link ( $ edge );
125- }
135+ foreach ( config ( ' erd-generator.relations. ' . $ relation -> getType (), []) as $ key => $ value ) {
136+ $ edge ->{ " set $ {key}" }( $ value );
126137 }
138+
139+ $ this ->graph ->link ($ edge );
140+ }
141+
142+ /**
143+ * @param Model $model
144+ * @param ModelRelation $relation
145+ * @param Node $modelNode
146+ * @param Node $relatedModelNode
147+ * @return void
148+ */
149+ protected function connectBelongsToMany (
150+ Model $ model ,
151+ ModelRelation $ relation ,
152+ Node $ modelNode ,
153+ Node $ relatedModelNode
154+ ): void {
155+ $ relationName = $ relation ->getName ();
156+ $ eloquentModel = app ($ model ->getModel ());
157+
158+ /** @var BelongsToMany $eloquentRelation */
159+ $ eloquentRelation = $ eloquentModel ->$ relationName ();
160+
161+ if (!$ eloquentRelation instanceof BelongsToMany) {
162+ return ;
163+ }
164+
165+ $ pivotClass = $ eloquentRelation ->getPivotClass ();
166+
167+ try {
168+ /** @var EloquentModel $relationModel */
169+ $ pivotModel = app ($ pivotClass );
170+ $ pivotModel ->setTable ($ eloquentRelation ->getTable ());
171+ $ label = (new \ReflectionClass ($ pivotClass ))->getShortName ();
172+ $ pivotTable = $ eloquentRelation ->getTable ();
173+ $ this ->addNodeToGraph ($ pivotModel , $ pivotTable , $ label );
174+
175+ $ pivotModelNode = $ this ->graph ->findNode ($ pivotTable );
176+
177+ $ relation = new ModelRelation (
178+ $ relationName ,
179+ 'BelongsToMany ' ,
180+ $ model ->getModel (),
181+ $ eloquentRelation ->getParent ()->getKeyName (),
182+ $ eloquentRelation ->getForeignPivotKeyName ()
183+ );
184+
185+ $ this ->connectNodes ($ modelNode , $ pivotModelNode , $ relation );
186+
187+ $ relation = new ModelRelation (
188+ $ relationName ,
189+ 'BelongsToMany ' ,
190+ $ model ->getModel (),
191+ $ eloquentRelation ->getRelatedPivotKeyName (),
192+ $ eloquentRelation ->getRelated ()->getKeyName ()
193+ );
194+
195+ $ this ->connectNodes ($ pivotModelNode , $ relatedModelNode , $ relation );
196+ } catch (\ReflectionException $ e ){}
197+ }
198+
199+ /**
200+ * @param Model $model
201+ * @param ModelRelation $relation
202+ * @param Node $modelNode
203+ * @param Node $relatedModelNode
204+ */
205+ protected function connectByRelation (
206+ Model $ model ,
207+ ModelRelation $ relation ,
208+ Node $ modelNode ,
209+ Node $ relatedModelNode
210+ ): void {
211+
212+ if ($ relation ->getType () === 'BelongsToMany ' ) {
213+ $ this ->connectBelongsToMany ($ model , $ relation , $ modelNode , $ relatedModelNode );
214+ return ;
215+ }
216+
217+ $ this ->connectNodes ($ modelNode , $ relatedModelNode , $ relation );
127218 }
128219}
0 commit comments