/** * Traverse an array of relationships and persist them * * @param Entity $metadata * @param object $entity * @param Reader $reader * @param string $local_id */ private function persistRelationshipsTraversal(Entity $metadata, $entity, Reader $reader, $local_id) { $relationships = $metadata->getRelationships(); $is_proxy = $entity instanceof OrmProxyInterface; foreach ($relationships as $relationship) { $key = $this->getRelationshipKey($relationship, $local_id); $value = $reader->getPropertyValue($relationship->getName()); // Skip relationship rules: // If the entity is not a proxy (i.e. a new entity) we still must allow for the scenario in which a new // entity is created over the top of an existing entity (same ID), as such, we still need to check every // relationship attached to the entity if (!$this->entity_manager->getMaintenanceMode() && $is_proxy) { /** @var OrmProxyInterface $entity */ // Check if we can skip the update if (!$entity->isRelativeModified($relationship->getName())) { // Looks like we can skip, but check inverted sort indices first - if ($relationship->getInversedBy()) { $inverse_relationship = $this->invertRelationship($relationship); if ($inverse_relationship->getSortableBy()) { // The inverse relationship has sortable columns, we need to check for local property // changes that might have impacted this - list(, , $maintain) = $this->getRelationshipDeltas($key, $relationship, $value); $this->updateMaintainedRelationshipSortIndices($inverse_relationship, $maintain, $reader, $local_id); } } // Nothing else to update on this relationship continue; } } // This condition allows NEW (not a proxy) entities that have NOT set a relationship to inherit existing // relationships which could be useful if the relationship was set by a foreign entity // See: docs/RaceConditions.md if ($is_proxy || $value || $this->entity_manager->getMaintenanceMode()) { $this->persistForwardRelationship($relationship, $key, $value); if (count($relationship->getSortableBy())) { $this->persistForwardSortIndices($relationship, $local_id, $value); } // Modify the inversed relationships if ($relationship->getInversedBy()) { $this->persistInversedRelationship($relationship, $key, $value, $local_id, $reader); } else { $this->persistRefs($relationship, $key, $value, $local_id); } } } }
/** * Compiles all columns for an entity * * @param Entity $md * @return array */ private function compileColumns(Entity $md) { $out = []; $columns = $md->getColumns(); foreach ($columns as $column) { $data = [Schema::COLUMN_TYPE => $column->getType()->value()]; if ($column->isId()) { $data[Schema::COLUMN_ID] = true; } $default_getter = 'get' . Inflector::classify($column->getProperty()); if ($column->getGetter() && $column->getGetter() != $default_getter) { $data[Schema::GETTER] = $column->getGetter(); } $default_setter = 'set' . Inflector::classify($column->getProperty()); if ($column->getSetter() && $column->getSetter() != $default_setter) { $data[Schema::SETTER] = $column->getSetter(); } if ($column->getClassName()) { $data[Schema::COLUMN_CLASS] = $column->getClassName(); } $out[$column->getName()] = $data; } $relationships = $md->getRelationships(); foreach ($relationships as $relationship) { $data = [Schema::REL_ASSOCIATION => $relationship->getRelationshipType()->value(), Schema::REL_TARGET => $relationship->getTarget()]; $default_getter = 'get' . Inflector::classify($relationship->getName()); if ($relationship->getGetter() && $relationship->getGetter() != $default_getter) { $data[Schema::GETTER] = $relationship->getGetter(); } $default_setter = 'set' . Inflector::classify($relationship->getName()); if ($relationship->getSetter() && $relationship->getSetter() != $default_setter) { $data[Schema::SETTER] = $relationship->getSetter(); } if ($relationship->getInversedBy()) { $data[Schema::REL_INVERSED_BY] = $relationship->getInversedBy(); } if ($relationship->getSortableBy()) { $data[Schema::SORT_INDICES] = $this->compileSortables($relationship->getSortableBy()); } $out[$relationship->getName()] = $data; } return $out; }