/** * @param DoplioDbTable $item * @param int $level */ private function flushItem(DoplioDbTable $item, $level = 0) { $parents = []; $children = []; foreach ($item->getRelations() as $relationshipName => $entity) { switch (true) { case $item->{$relationshipName}() instanceof BelongsTo: $parents[$relationshipName] = $entity; break; default: $children[$relationshipName] = $entity; break; } } if ($level == 0 || $level == 1) { // Flush parents first (belongsTo) foreach ($parents as $relationshipName => $parent) { if ($parent instanceof Collection) { foreach ($parent as $collectionParent) { if (!$collectionParent) { $item->{$relationshipName}()->dissociate(); continue; } $collectionParent = $this->sync($collectionParent); if (!$collectionParent) { $item->{$relationshipName}()->dissociate(); continue; } $this->flushItem($collectionParent); $item->{$relationshipName}()->associate($collectionParent); } continue; } if (!$parent) { $item->{$relationshipName}()->dissociate(); continue; } $parent = $this->sync($parent); if (!$parent) { $item->{$relationshipName}()->dissociate(); continue; } $this->flushItem($parent); $item->{$relationshipName}()->associate($parent); } } if ($level == 0) { $item->save(); } if ($level == 0 || ($level = 2)) { // Flush children's (hasOne/hasMany) foreach ($children as $relationshipName => $child) { if ($child instanceof Collection) { foreach ($child as $collectionChild) { $collectionChild = $this->sync($collectionChild); $this->flushItem($collectionChild, 1); $item->{$relationshipName}()->save($collectionChild); $this->flushItem($collectionChild, 2); } continue; } $child = $this->sync($child); $this->flushItem($child, 1); $item->{$relationshipName}()->save($child); $this->flushItem($child, 2); } } }