/** * Validates & completes the basic mapping information that is common to all * association mappings (one-to-one, many-ot-one, one-to-many, many-to-many). * * @param array $mapping The mapping. * @return array The updated mapping. * @throws MappingException If something is wrong with the mapping. */ protected function _validateAndCompleteAssociationMapping(array $mapping) { if (!isset($mapping['mappedBy'])) { $mapping['mappedBy'] = null; } if (!isset($mapping['inversedBy'])) { $mapping['inversedBy'] = null; } $mapping['isOwningSide'] = true; // assume owning side until we hit mappedBy // unset optional indexBy attribute if its empty if (!isset($mapping['indexBy']) || !$mapping['indexBy']) { unset($mapping['indexBy']); } // If targetEntity is unqualified, assume it is in the same namespace as // the sourceEntity. $mapping['sourceEntity'] = $this->name; if (isset($mapping['targetEntity'])) { if (strlen($this->namespace) > 0 && strpos($mapping['targetEntity'], '\\') === false) { $mapping['targetEntity'] = $this->namespace . '\\' . $mapping['targetEntity']; } $mapping['targetEntity'] = ltrim($mapping['targetEntity'], '\\'); } if (($mapping['type'] & self::MANY_TO_ONE) > 0 && isset($mapping['orphanRemoval']) && $mapping['orphanRemoval'] == true) { throw MappingException::illegalOrphanRemoval($this->name, $mapping['fieldName']); } // Complete id mapping if (isset($mapping['id']) && $mapping['id'] === true) { if (isset($mapping['orphanRemoval']) && $mapping['orphanRemoval'] == true) { throw MappingException::illegalOrphanRemovalOnIdentifierAssociation($this->name, $mapping['fieldName']); } if (!in_array($mapping['fieldName'], $this->identifier)) { if (count($mapping['joinColumns']) >= 2) { throw MappingException::cannotMapCompositePrimaryKeyEntitiesAsForeignId($mapping['targetEntity'], $this->name, $mapping['fieldName']); } $this->identifier[] = $mapping['fieldName']; $this->containsForeignIdentifier = true; } // Check for composite key if (!$this->isIdentifierComposite && count($this->identifier) > 1) { $this->isIdentifierComposite = true; } } // Mandatory attributes for both sides // Mandatory: fieldName, targetEntity if (!isset($mapping['fieldName']) || strlen($mapping['fieldName']) == 0) { throw MappingException::missingFieldName($this->name); } if (!isset($mapping['targetEntity'])) { throw MappingException::missingTargetEntity($mapping['fieldName']); } // Mandatory and optional attributes for either side if (!$mapping['mappedBy']) { if (isset($mapping['joinTable']) && $mapping['joinTable']) { if (isset($mapping['joinTable']['name']) && $mapping['joinTable']['name'][0] === '`') { $mapping['joinTable']['name'] = trim($mapping['joinTable']['name'], '`'); $mapping['joinTable']['quoted'] = true; } } } else { $mapping['isOwningSide'] = false; } if (isset($mapping['id']) && $mapping['id'] === true && $mapping['type'] & self::TO_MANY) { throw MappingException::illegalToManyIdentifierAssoaction($this->name, $mapping['fieldName']); } // Fetch mode. Default fetch mode to LAZY, if not set. if (!isset($mapping['fetch'])) { $mapping['fetch'] = self::FETCH_LAZY; } // Cascades $cascades = isset($mapping['cascade']) ? array_map('strtolower', $mapping['cascade']) : array(); if (in_array('all', $cascades)) { $cascades = array('remove', 'persist', 'refresh', 'merge', 'detach'); } if (count($cascades) !== count(array_intersect($cascades, array('remove', 'persist', 'refresh', 'merge', 'detach')))) { throw MappingException::invalidCascadeOption(array_diff($cascades, array_intersect($cascades, array('remove', 'persist', 'refresh', 'merge', 'detach'))), $this->name, $mapping['fieldName']); } $mapping['cascade'] = $cascades; $mapping['isCascadeRemove'] = in_array('remove', $cascades); $mapping['isCascadePersist'] = in_array('persist', $cascades); $mapping['isCascadeRefresh'] = in_array('refresh', $cascades); $mapping['isCascadeMerge'] = in_array('merge', $cascades); $mapping['isCascadeDetach'] = in_array('detach', $cascades); return $mapping; }