protected function saveManyToMany(array $relationship, $alias, Collection $collection, EntityMetadata $childMetadata, $ourValue, $ourField, $theirField) { if (!empty($this->relationshipCascade[$alias])) { /** @var RepositoryInterface $childRepo */ $childRepo = $this->relationshipCascade[$alias]; // save all entities currently in the collection foreach ($collection->getAddedEntities() as $child) { $childRepo->save($child); } } // We will be doing operations on an intermediary join table. As Reposition works with EntityMetadata, we // need to create the metadata for the intermediary $intermediaryMetadata = $this->metadataProvider->getEntityMetadataForIntermediary($relationship[EntityMetadata::METADATA_RELATIONSHIP_JOIN_TABLE]); // generate the relationship metadata used on this collection $intermediaryRelationship = [EntityMetadata::METADATA_RELATIONSHIP_TYPE => EntityMetadata::RELATIONSHIP_TYPE_MANY_TO_ONE]; $manyToManyRelationships = ["ours" => $this->entityMetadata->getCollection() . "_" . $ourField, "theirs" => $childMetadata->getCollection() . "_" . $theirField]; foreach ($manyToManyRelationships as $relationshipAlias => $intermediaryOurField) { $intermediaryRelationship[EntityMetadata::METADATA_RELATIONSHIP_OUR_FIELD] = $intermediaryOurField; $intermediaryRelationship[EntityMetadata::METADATA_RELATIONSHIP_ALIAS] = $relationshipAlias; $intermediaryMetadata->addRelationshipMetadata($this->entityMetadata->getEntity(), $intermediaryRelationship); } // process added and removed children $added = $collection->getAddedEntities(); $removed = $collection->getRemovedEntities(); if (!empty($added)) { $insert = $this->queryBuilder->save($intermediaryMetadata, ["saveType" => "insert"]); // create an array of values to use, for each entity we're adding foreach ($added as $child) { // we have to use the actual field names here as we're saving an array, rather than a class instance $entityArray = [$manyToManyRelationships["ours"] => $ourValue, $manyToManyRelationships["theirs"] => $childMetadata->getEntityValue($child, $theirField)]; $insert->entity($entityArray); } $this->doQuery($insert, ["output" => "raw"]); } if (!empty($removed)) { $delete = $this->queryBuilder->delete($intermediaryMetadata); // delete rows where the parent value is X and the child value is in the list $filters = ["ours" => $ourValue, "theirs" => $this->condition("in", $removed)]; $this->createWhereFromFilters($delete, $filters); $this->doQuery($delete, ["output" => "raw"]); } }