/**
  * @dataProvider dataJoinTableName
  *
  * @param NamingStrategy $strategy
  * @param string $expected
  * @param string $ownerEntity
  * @param string $associatedEntity
  * @param string $propertyName
  */
 public function testJoinTableName(NamingStrategy $strategy, $expected, $ownerEntity, $associatedEntity, $propertyName = null)
 {
     $this->assertEquals($expected, $strategy->joinTableName($ownerEntity, $associatedEntity, $propertyName));
 }
 protected function _validateAndCompleteManyToManyMapping(array $mapping)
 {
     $mapping = $this->_validateAndCompleteAssociationMapping($mapping);
     if ($mapping['isOwningSide']) {
         // owning side MUST have a join table
         if (!isset($mapping['joinTable']['name'])) {
             $mapping['joinTable']['name'] = $this->namingStrategy->joinTableName($mapping['sourceEntity'], $mapping['targetEntity'], $mapping['fieldName']);
         }
         if (!isset($mapping['joinTable']['joinColumns'])) {
             $mapping['joinTable']['joinColumns'] = array(array('name' => $this->namingStrategy->joinKeyColumnName($mapping['sourceEntity']), 'referencedColumnName' => $this->namingStrategy->referenceColumnName(), 'onDelete' => 'CASCADE'));
         }
         if (!isset($mapping['joinTable']['inverseJoinColumns'])) {
             $mapping['joinTable']['inverseJoinColumns'] = array(array('name' => $this->namingStrategy->joinKeyColumnName($mapping['targetEntity']), 'referencedColumnName' => $this->namingStrategy->referenceColumnName(), 'onDelete' => 'CASCADE'));
         }
         $mapping['joinTableColumns'] = array();
         foreach ($mapping['joinTable']['joinColumns'] as &$joinColumn) {
             if (empty($joinColumn['name'])) {
                 $joinColumn['name'] = $this->namingStrategy->joinKeyColumnName($mapping['sourceEntity'], $joinColumn['referencedColumnName']);
             }
             if (empty($joinColumn['referencedColumnName'])) {
                 $joinColumn['referencedColumnName'] = $this->namingStrategy->referenceColumnName();
             }
             if ($joinColumn['name'][0] === '`') {
                 $joinColumn['name'] = trim($joinColumn['name'], '`');
                 $joinColumn['quoted'] = true;
             }
             if ($joinColumn['referencedColumnName'][0] === '`') {
                 $joinColumn['referencedColumnName'] = trim($joinColumn['referencedColumnName'], '`');
                 $joinColumn['quoted'] = true;
             }
             if (isset($joinColumn['onDelete']) && strtolower($joinColumn['onDelete']) == 'cascade') {
                 $mapping['isOnDeleteCascade'] = true;
             }
             $mapping['relationToSourceKeyColumns'][$joinColumn['name']] = $joinColumn['referencedColumnName'];
             $mapping['joinTableColumns'][] = $joinColumn['name'];
         }
         foreach ($mapping['joinTable']['inverseJoinColumns'] as &$inverseJoinColumn) {
             if (empty($inverseJoinColumn['name'])) {
                 $inverseJoinColumn['name'] = $this->namingStrategy->joinKeyColumnName($mapping['targetEntity'], $inverseJoinColumn['referencedColumnName']);
             }
             if (empty($inverseJoinColumn['referencedColumnName'])) {
                 $inverseJoinColumn['referencedColumnName'] = $this->namingStrategy->referenceColumnName();
             }
             if ($inverseJoinColumn['name'][0] === '`') {
                 $inverseJoinColumn['name'] = trim($inverseJoinColumn['name'], '`');
                 $inverseJoinColumn['quoted'] = true;
             }
             if ($inverseJoinColumn['referencedColumnName'][0] === '`') {
                 $inverseJoinColumn['referencedColumnName'] = trim($inverseJoinColumn['referencedColumnName'], '`');
                 $inverseJoinColumn['quoted'] = true;
             }
             if (isset($inverseJoinColumn['onDelete']) && strtolower($inverseJoinColumn['onDelete']) == 'cascade') {
                 $mapping['isOnDeleteCascade'] = true;
             }
             $mapping['relationToTargetKeyColumns'][$inverseJoinColumn['name']] = $inverseJoinColumn['referencedColumnName'];
             $mapping['joinTableColumns'][] = $inverseJoinColumn['name'];
         }
     }
     $mapping['orphanRemoval'] = isset($mapping['orphanRemoval']) ? (bool) $mapping['orphanRemoval'] : false;
     if (isset($mapping['orderBy'])) {
         if (!is_array($mapping['orderBy'])) {
             throw new InvalidArgumentException("'orderBy' is expected to be an array, not " . gettype($mapping['orderBy']));
         }
     }
     return $mapping;
 }
 /**
  * Validates & completes a many-to-many association mapping.
  *
  * @param array $mapping The mapping to validate & complete.
  *
  * @return array The validated & completed mapping.
  *
  * @throws \InvalidArgumentException
  */
 protected function _validateAndCompleteManyToManyMapping(array $mapping)
 {
     $mapping = $this->_validateAndCompleteAssociationMapping($mapping);
     if ($mapping['isOwningSide']) {
         // owning side MUST have a join table
         if (!isset($mapping['joinTable']['name'])) {
             $mapping['joinTable']['name'] = $this->namingStrategy->joinTableName($mapping['sourceEntity'], $mapping['targetEntity'], $mapping['fieldName']);
         }
         $selfReferencingEntityWithoutJoinColumns = $mapping['sourceEntity'] == $mapping['targetEntity'] && !(isset($mapping['joinTable']['joinColumns']) || isset($mapping['joinTable']['inverseJoinColumns']));
         if (!isset($mapping['joinTable']['joinColumns'])) {
             $mapping['joinTable']['joinColumns'] = [['name' => $this->namingStrategy->joinKeyColumnName($mapping['sourceEntity'], $selfReferencingEntityWithoutJoinColumns ? 'source' : null), 'referencedColumnName' => $this->namingStrategy->referenceColumnName(), 'onDelete' => 'CASCADE']];
         }
         if (!isset($mapping['joinTable']['inverseJoinColumns'])) {
             $mapping['joinTable']['inverseJoinColumns'] = [['name' => $this->namingStrategy->joinKeyColumnName($mapping['targetEntity'], $selfReferencingEntityWithoutJoinColumns ? 'target' : null), 'referencedColumnName' => $this->namingStrategy->referenceColumnName(), 'onDelete' => 'CASCADE']];
         }
         $mapping['joinTableColumns'] = [];
         foreach ($mapping['joinTable']['joinColumns'] as &$joinColumn) {
             if (empty($joinColumn['name'])) {
                 $joinColumn['name'] = $this->namingStrategy->joinKeyColumnName($mapping['sourceEntity'], $joinColumn['referencedColumnName']);
             }
             if (empty($joinColumn['referencedColumnName'])) {
                 $joinColumn['referencedColumnName'] = $this->namingStrategy->referenceColumnName();
             }
             if ($joinColumn['name'][0] === '`') {
                 $joinColumn['name'] = trim($joinColumn['name'], '`');
                 $joinColumn['quoted'] = true;
             }
             if ($joinColumn['referencedColumnName'][0] === '`') {
                 $joinColumn['referencedColumnName'] = trim($joinColumn['referencedColumnName'], '`');
                 $joinColumn['quoted'] = true;
             }
             if (isset($joinColumn['onDelete']) && strtolower($joinColumn['onDelete']) == 'cascade') {
                 $mapping['isOnDeleteCascade'] = true;
             }
             $mapping['relationToSourceKeyColumns'][$joinColumn['name']] = $joinColumn['referencedColumnName'];
             $mapping['joinTableColumns'][] = $joinColumn['name'];
         }
         foreach ($mapping['joinTable']['inverseJoinColumns'] as &$inverseJoinColumn) {
             if (empty($inverseJoinColumn['name'])) {
                 $inverseJoinColumn['name'] = $this->namingStrategy->joinKeyColumnName($mapping['targetEntity'], $inverseJoinColumn['referencedColumnName']);
             }
             if (empty($inverseJoinColumn['referencedColumnName'])) {
                 $inverseJoinColumn['referencedColumnName'] = $this->namingStrategy->referenceColumnName();
             }
             if ($inverseJoinColumn['name'][0] === '`') {
                 $inverseJoinColumn['name'] = trim($inverseJoinColumn['name'], '`');
                 $inverseJoinColumn['quoted'] = true;
             }
             if ($inverseJoinColumn['referencedColumnName'][0] === '`') {
                 $inverseJoinColumn['referencedColumnName'] = trim($inverseJoinColumn['referencedColumnName'], '`');
                 $inverseJoinColumn['quoted'] = true;
             }
             if (isset($inverseJoinColumn['onDelete']) && strtolower($inverseJoinColumn['onDelete']) == 'cascade') {
                 $mapping['isOnDeleteCascade'] = true;
             }
             $mapping['relationToTargetKeyColumns'][$inverseJoinColumn['name']] = $inverseJoinColumn['referencedColumnName'];
             $mapping['joinTableColumns'][] = $inverseJoinColumn['name'];
         }
     }
     $mapping['orphanRemoval'] = isset($mapping['orphanRemoval']) && $mapping['orphanRemoval'];
     $this->assertMappingOrderBy($mapping);
     return $mapping;
 }