@@ -104,20 +104,35 @@ abstract class Entity extends Model implements
104
104
'owned_by ' ,
105
105
];
106
106
107
- public function newFromBuilder ($ attributes = [], $ connection = null ): static
107
+ // TODO - To Remove, reduce contents/relatedData to just one of them.
108
+ // TODO - Update/remove existing usages of contents/relatedData
109
+ // TODO - Review usages of query-time update or mass insert of entity model data since those will still need to consider the multi-table layout.
110
+
111
+ /**
112
+ * Override the save method to also save the contents for convenience.
113
+ */
114
+ public function save (array $ options = []): bool
108
115
{
109
- $ entityFields = array_intersect_key ( $ attributes , array_flip ( static :: $ commonFields ) );
110
- $ extraFields = array_diff_key ( $ attributes , $ entityFields );
116
+ $ contents = $ this -> relatedData ()-> firstOrNew ( );
117
+ $ contentFields = $ this -> getContentsAttributes ( );
111
118
112
- $ instance = parent ::newFromBuilder ($ entityFields , $ connection );
113
- $ data = $ instance ->relatedData ()->newModelInstance ()->newFromBuilder ($ extraFields , $ connection );
119
+ foreach ($ contentFields as $ key => $ value ) {
120
+ $ contents ->setAttribute ($ key , $ value );
121
+ unset($ this ->attributes [$ key ]);
122
+ }
114
123
115
- $ instance ->setRelation ('contents ' , $ data );
124
+ $ result = parent ::save ($ options );
125
+ $ contentsResult = true ;
116
126
117
- return $ instance ;
118
- }
127
+ if ($ result && $ contents ->isDirty ()) {
128
+ $ contentsResult = $ contents ->save ();
129
+ $ this ->touch ();
130
+ }
119
131
120
- // TODO - Move attribute usage to `->contents()->attr` calls
132
+ $ this ->forceFill ($ contentFields );
133
+
134
+ return $ result && $ contentsResult ;
135
+ }
121
136
122
137
/**
123
138
* Check if this item is a container item.
@@ -187,7 +202,7 @@ public function matchesOrContains(self $entity): bool
187
202
}
188
203
189
204
if ($ entity instanceof Page && $ this instanceof Chapter) {
190
- return $ entity ->contents ()-> chapter_id === $ this ->id ;
205
+ return $ entity ->chapter_id === $ this ->id ;
191
206
}
192
207
193
208
return false ;
@@ -438,19 +453,36 @@ public function logDescriptor(): string
438
453
abstract public function relatedData (): HasOne ;
439
454
440
455
/**
441
- * Get the contents of this entity.
456
+ * Get the attributes that are intended for the related contents model.
457
+ * @return array<string, mixed>
442
458
*/
443
- public function contents (): EntityContainerContents | EntityPageContents | null
459
+ protected function getContentsAttributes (): array
444
460
{
445
- if ($ this ->relationLoaded ('contents ' )) {
446
- return $ this ->getRelation ('contents ' );
447
- }
461
+ $ contentFields = [];
448
462
449
- $ relatedData = $ this ->relatedData ()->first ();
450
- if ($ relatedData ) {
451
- return $ relatedData ;
463
+ foreach ($ this ->attributes as $ key => $ value ) {
464
+ if (!in_array ($ key , static ::$ commonFields )) {
465
+ $ contentFields [$ key ] = $ value ;
466
+ }
452
467
}
453
468
454
- return null ;
469
+ return $ contentFields ;
470
+ }
471
+
472
+ /**
473
+ * Get the contents model of this entity.
474
+ * Should only really be used if accessing the methods of the contents model
475
+ * since the properties would already be part of the fetched entity model.
476
+ */
477
+ public function contents (): EntityContainerContents |EntityPageContents
478
+ {
479
+ $ contentsData = $ this ->getContentsAttributes ();
480
+
481
+ /**
482
+ * @var EntityContainerContents|EntityPageContents $instance
483
+ */
484
+ $ instance = $ this ->relatedData ()->newModelInstance ()->newFromBuilder ($ contentsData , $ this ->getConnection ());
485
+
486
+ return $ instance ;
455
487
}
456
488
}
0 commit comments