/** * Gets the conditional SQL fragment used in the WHERE clause when selecting * entities in this persister. * * Subclasses are supposed to override this method if they intend to change * or alter the criteria by which entities are selected. * * @param array $criteria * @param AssociationMapping $assoc * @return string */ protected function _getSelectConditionSQL(array $criteria, $assoc = null) { $conditionSql = ''; foreach ($criteria as $field => $value) { $conditionSql .= $conditionSql ? ' AND ' : ''; if (isset($this->_class->columnNames[$field])) { if (isset($this->_class->fieldMappings[$field]['inherited'])) { $conditionSql .= $this->_getSQLTableAlias($this->_class->fieldMappings[$field]['inherited']) . '.'; } else { $conditionSql .= $this->_getSQLTableAlias($this->_class->name) . '.'; } $conditionSql .= $this->_class->getQuotedColumnName($field, $this->_platform); } else { if (isset($this->_class->associationMappings[$field])) { if (!$this->_class->associationMappings[$field]['isOwningSide']) { throw ORMException::invalidFindByInverseAssociation($this->_class->name, $field); } if (isset($this->_class->associationMappings[$field]['inherited'])) { $conditionSql .= $this->_getSQLTableAlias($this->_class->associationMappings[$field]['inherited']) . '.'; } else { $conditionSql .= $this->_getSQLTableAlias($this->_class->name) . '.'; } $conditionSql .= $this->_class->associationMappings[$field]['joinColumns'][0]['name']; } else { if ($assoc !== null) { if ($assoc['type'] == ClassMetadata::MANY_TO_MANY) { $owningAssoc = $assoc['isOwningSide'] ? $assoc : $this->_em->getClassMetadata($assoc['targetEntity'])->associationMappings[$assoc['mappedBy']]; $conditionSql .= $this->_class->getQuotedJoinTableName($owningAssoc, $this->_platform) . '.' . $field; } else { $conditionSql .= $field; } } else { throw ORMException::unrecognizedField($field); } } } $conditionSql .= ' = ?'; } return $conditionSql; }
/** * Gets the conditional SQL fragment used in the WHERE clause when selecting * entities in this persister. * * Subclasses are supposed to override this method if they intend to change * or alter the criteria by which entities are selected. * * @param array $criteria * @param AssociationMapping $assoc * @return string */ protected function _getSelectConditionSQL(array $criteria, $assoc = null) { $conditionSql = ''; foreach ($criteria as $field => $value) { $conditionSql .= $conditionSql ? ' AND ' : ''; if (isset($this->_class->columnNames[$field])) { if (isset($this->_class->fieldMappings[$field]['inherited'])) { $conditionSql .= $this->_getSQLTableAlias($this->_class->fieldMappings[$field]['inherited']) . '.'; } else { $conditionSql .= $this->_getSQLTableAlias($this->_class->name) . '.'; } $conditionSql .= $this->_class->getQuotedColumnName($field, $this->_platform); } else { if (isset($this->_class->associationMappings[$field])) { if (!$this->_class->associationMappings[$field]['isOwningSide']) { throw ORMException::invalidFindByInverseAssociation($this->_class->name, $field); } if (isset($this->_class->associationMappings[$field]['inherited'])) { $conditionSql .= $this->_getSQLTableAlias($this->_class->associationMappings[$field]['inherited']) . '.'; } else { $conditionSql .= $this->_getSQLTableAlias($this->_class->name) . '.'; } $conditionSql .= $this->_class->associationMappings[$field]['joinColumns'][0]['name']; } else { if ($assoc !== null && strpos($field, " ") === false && strpos($field, "(") === false) { // very careless developers could potentially open up this normally hidden api for userland attacks, // therefore checking for spaces and function calls which are not allowed. // found a join column condition, not really a "field" $conditionSql .= $field; } else { throw ORMException::unrecognizedField($field); } } } $conditionSql .= is_array($value) ? ' IN (?)' : ($value === null ? ' IS NULL' : ' = ?'); } return $conditionSql; }
/** * Builds the left-hand-side of a where condition statement. * * @param string $field * @param array|null $assoc * * @return string[] * * @throws \Doctrine\ORM\ORMException */ private function getSelectConditionStatementColumnSQL($field, $assoc = null) { if (isset($this->class->columnNames[$field])) { $className = isset($this->class->fieldMappings[$field]['inherited']) ? $this->class->fieldMappings[$field]['inherited'] : $this->class->name; return array($this->getSQLTableAlias($className) . '.' . $this->quoteStrategy->getColumnName($field, $this->class, $this->platform)); } if (isset($this->class->associationMappings[$field])) { $association = $this->class->associationMappings[$field]; // Many-To-Many requires join table check for joinColumn $columns = array(); $class = $this->class; if ($association['type'] === ClassMetadata::MANY_TO_MANY) { if (!$association['isOwningSide']) { $association = $assoc; } $joinTableName = $this->quoteStrategy->getJoinTableName($association, $class, $this->platform); $joinColumns = $assoc['isOwningSide'] ? $association['joinTable']['joinColumns'] : $association['joinTable']['inverseJoinColumns']; foreach ($joinColumns as $joinColumn) { $columns[] = $joinTableName . '.' . $this->quoteStrategy->getJoinColumnName($joinColumn, $class, $this->platform); } } else { if (!$association['isOwningSide']) { throw ORMException::invalidFindByInverseAssociation($this->class->name, $field); } $className = isset($association['inherited']) ? $association['inherited'] : $this->class->name; foreach ($association['joinColumns'] as $joinColumn) { $columns[] = $this->getSQLTableAlias($className) . '.' . $this->quoteStrategy->getJoinColumnName($joinColumn, $this->class, $this->platform); } } return $columns; } if ($assoc !== null && strpos($field, " ") === false && strpos($field, "(") === false) { // very careless developers could potentially open up this normally hidden api for userland attacks, // therefore checking for spaces and function calls which are not allowed. // found a join column condition, not really a "field" return array($field); } throw ORMException::unrecognizedField($field); }
/** * Builds the left-hand-side of a where condition statement. * * @param string $field * @param array|null $assoc * * @return string * * @throws \Doctrine\ORM\ORMException */ protected function getSelectConditionStatementColumnSQL($field, $assoc = null) { if (isset($this->class->columnNames[$field])) { $className = (isset($this->class->fieldMappings[$field]['inherited'])) ? $this->class->fieldMappings[$field]['inherited'] : $this->class->name; return $this->getSQLTableAlias($className) . '.' . $this->quoteStrategy->getColumnName($field, $this->class, $this->platform); } if (isset($this->class->associationMappings[$field])) { if ( ! $this->class->associationMappings[$field]['isOwningSide']) { throw ORMException::invalidFindByInverseAssociation($this->class->name, $field); } $joinColumn = $this->class->associationMappings[$field]['joinColumns'][0]; $className = (isset($this->class->associationMappings[$field]['inherited'])) ? $this->class->associationMappings[$field]['inherited'] : $this->class->name; return $this->getSQLTableAlias($className) . '.' . $this->quoteStrategy->getJoinColumnName($joinColumn, $this->class, $this->platform); } if ($assoc !== null && strpos($field, " ") === false && strpos($field, "(") === false) { // very careless developers could potentially open up this normally hidden api for userland attacks, // therefore checking for spaces and function calls which are not allowed. // found a join column condition, not really a "field" return $field; } throw ORMException::unrecognizedField($field); }
/** * @expectedException \Symfony\Component\Validator\Exception\ConstraintDefinitionException * @expectedExceptionMessage During the validation whether the given property is unique or not, doctrine threw an exception with the following message: "Unrecognized field: test-field". Did you misconfigure any parameters such as the field or entity name? */ public function testFindOneByThrowsORMException() { $repository = $this->getMockWithoutInvokingTheOriginalConstructor(EntityRepository::class); $repository->expects($this->once())->method('findOneBy')->with(['test-field' => 'test'])->willReturnCallback(function () { throw ORMException::unrecognizedField('test-field'); }); $manager = $this->getMock(ObjectManager::class); $manager->expects($this->any())->method('getRepository')->willReturn($repository); $mockRegistry = $this->getMock(ManagerRegistry::class); $mockRegistry->expects($this->any())->method('getManagerForClass')->willReturn($manager); $propertyMock = new UniquePropertyValidator($mockRegistry); $propertyMock->initialize($this->getMock(ExecutionContextInterface::class)); $propertyMock->validate('test', new UniqueProperty(['entity' => 'AnotherMapping:User', 'field' => 'test-field'])); }
/** * Generate ORDER BY SQL snippet for ordered collections. * * @param array $orderBy * @param string $baseTableAlias * @return string */ protected function _getCollectionOrderBySQL(array $orderBy, $baseTableAlias) { $orderBySql = ''; foreach ($orderBy as $fieldName => $orientation) { if (!isset($this->_class->fieldMappings[$fieldName])) { ORMException::unrecognizedField($fieldName); } $tableAlias = isset($this->_class->fieldMappings[$fieldName]['inherited']) ? $this->_getSQLTableAlias($this->_em->getClassMetadata($this->_class->fieldMappings[$fieldName]['inherited'])) : $baseTableAlias; $columnName = $this->_class->getQuotedColumnName($fieldName, $this->_platform); if ($orderBySql != '') { $orderBySql .= ', '; } else { $orderBySql = ' ORDER BY '; } $orderBySql .= $tableAlias . '.' . $columnName . ' ' . $orientation; } return $orderBySql; }
/** * Gets the SELECT SQL to select one or more entities by a set of field criteria. * * @param array $criteria * @return string The SQL. * @override */ protected function _getSelectEntitiesSql(array &$criteria, $assoc = null) { $tableAliases = array(); $aliasIndex = 1; $idColumns = $this->_class->getIdentifierColumnNames(); $baseTableAlias = 't0'; $setResultColumnNames = empty($this->_resultColumnNames); foreach (array_merge($this->_class->subClasses, $this->_class->parentClasses) as $className) { $tableAliases[$className] = 't' . $aliasIndex++; } // Add regular columns $columnList = ''; foreach ($this->_class->fieldMappings as $fieldName => $mapping) { $tableAlias = isset($mapping['inherited']) ? $tableAliases[$mapping['inherited']] : $baseTableAlias; if ($columnList != '') { $columnList .= ', '; } $columnList .= $tableAlias . '.' . $this->_class->getQuotedColumnName($fieldName, $this->_platform); if ($setResultColumnNames) { $resultColumnName = $this->_platform->getSqlResultCasing($mapping['columnName']); $this->_resultColumnNames[$resultColumnName] = $mapping['columnName']; } } // Add foreign key columns foreach ($this->_class->associationMappings as $assoc2) { if ($assoc2->isOwningSide && $assoc2->isOneToOne()) { foreach ($assoc2->targetToSourceKeyColumns as $srcColumn) { $columnList .= ', ' . $assoc2->getQuotedJoinColumnName($srcColumn, $this->_platform); if ($setResultColumnNames) { $resultColumnName = $this->_platform->getSqlResultCasing($srcColumn); $this->_resultColumnNames[$resultColumnName] = $srcColumn; } } } } // Add discriminator column if ($this->_class->rootEntityName == $this->_class->name) { $columnList .= ', ' . $baseTableAlias . '.' . $this->_class->getQuotedDiscriminatorColumnName($this->_platform); } else { $columnList .= ', ' . $tableAliases[$this->_class->rootEntityName] . '.' . $this->_class->getQuotedDiscriminatorColumnName($this->_platform); } if ($setResultColumnNames) { $resultColumnName = $this->_platform->getSqlResultCasing($this->_class->discriminatorColumn['name']); $this->_resultColumnNames[$resultColumnName] = $this->_class->discriminatorColumn['name']; } // INNER JOIN parent tables $joinSql = ''; foreach ($this->_class->parentClasses as $parentClassName) { $parentClass = $this->_em->getClassMetadata($parentClassName); $tableAlias = $tableAliases[$parentClassName]; $joinSql .= ' INNER JOIN ' . $parentClass->getQuotedTableName($this->_platform) . ' ' . $tableAlias . ' ON '; $first = true; foreach ($idColumns as $idColumn) { if ($first) { $first = false; } else { $joinSql .= ' AND '; } $joinSql .= $baseTableAlias . '.' . $idColumn . ' = ' . $tableAlias . '.' . $idColumn; } } // OUTER JOIN sub tables foreach ($this->_class->subClasses as $subClassName) { $subClass = $this->_em->getClassMetadata($subClassName); $tableAlias = $tableAliases[$subClassName]; // Add subclass columns foreach ($subClass->fieldMappings as $fieldName => $mapping) { if (isset($mapping['inherited'])) { continue; } $columnList .= ', ' . $tableAlias . '.' . $subClass->getQuotedColumnName($fieldName, $this->_platform); if ($setResultColumnNames) { $resultColumnName = $this->_platform->getSqlResultCasing($mapping['columnName']); $this->_resultColumnNames[$resultColumnName] = $mapping['columnName']; } } // Add join columns (foreign keys) foreach ($subClass->associationMappings as $assoc2) { if ($assoc2->isOwningSide && $assoc2->isOneToOne() && !isset($subClass->inheritedAssociationFields[$assoc2->sourceFieldName])) { foreach ($assoc2->targetToSourceKeyColumns as $srcColumn) { $columnList .= ', ' . $tableAlias . '.' . $assoc2->getQuotedJoinColumnName($srcColumn, $this->_platform); if ($setResultColumnNames) { $resultColumnName = $this->_platform->getSqlResultCasing($srcColumn); $this->_resultColumnNames[$resultColumnName] = $srcColumn; } } } } // Add LEFT JOIN $joinSql .= ' LEFT JOIN ' . $subClass->getQuotedTableName($this->_platform) . ' ' . $tableAlias . ' ON '; $first = true; foreach ($idColumns as $idColumn) { if ($first) { $first = false; } else { $joinSql .= ' AND '; } $joinSql .= $baseTableAlias . '.' . $idColumn . ' = ' . $tableAlias . '.' . $idColumn; } } $conditionSql = ''; foreach ($criteria as $field => $value) { if ($conditionSql != '') { $conditionSql .= ' AND '; } $conditionSql .= $baseTableAlias . '.'; if (isset($this->_class->columnNames[$field])) { $conditionSql .= $this->_class->getQuotedColumnName($field, $this->_platform); } else { if ($assoc !== null) { $conditionSql .= $assoc->getQuotedJoinColumnName($field, $this->_platform); } else { throw ORMException::unrecognizedField($field); } } $conditionSql .= ' = ?'; } return 'SELECT ' . $columnList . ' FROM ' . $this->_class->getQuotedTableName($this->_platform) . ' ' . $baseTableAlias . $joinSql . ($conditionSql != '' ? ' WHERE ' . $conditionSql : ''); }
/** * Gets the conditional SQL fragment used in the WHERE clause when selecting * entities in this persister. * * Subclasses are supposed to override this method if they intend to change * or alter the criteria by which entities are selected. * * @param array $criteria * @param AssociationMapping $assoc * @return string */ protected function _getSelectConditionSQL(array $criteria, $assoc = null) { $conditionSql = ''; foreach ($criteria as $field => $value) { $conditionSql .= $conditionSql ? ' AND ' : ''; $placeholder = '?'; if (isset($this->_class->columnNames[$field])) { $className = isset($this->_class->fieldMappings[$field]['inherited']) ? $this->_class->fieldMappings[$field]['inherited'] : $this->_class->name; $conditionSql .= $this->_getSQLTableAlias($className) . '.' . $this->_class->getQuotedColumnName($field, $this->_platform); if (isset($this->_class->fieldMappings[$field]['requireSQLConversion'])) { $type = Type::getType($this->_class->getTypeOfField($field)); $placeholder = $type->convertToDatabaseValueSQL($placeholder, $this->_platform); } } else { if (isset($this->_class->associationMappings[$field])) { if (!$this->_class->associationMappings[$field]['isOwningSide']) { throw ORMException::invalidFindByInverseAssociation($this->_class->name, $field); } $className = isset($this->_class->associationMappings[$field]['inherited']) ? $this->_class->associationMappings[$field]['inherited'] : $this->_class->name; $conditionSql .= $this->_getSQLTableAlias($className) . '.' . $this->_class->associationMappings[$field]['joinColumns'][0]['name']; } else { if ($assoc !== null && strpos($field, " ") === false && strpos($field, "(") === false) { // very careless developers could potentially open up this normally hidden api for userland attacks, // therefore checking for spaces and function calls which are not allowed. // found a join column condition, not really a "field" $conditionSql .= $field; } else { throw ORMException::unrecognizedField($field); } } } //echo preg_match("/(like)/i",$value)?'ok - ':'not - '; $conditionSql .= is_array($value) ? ' IN (?)' : ($value === null ? ' IS NULL' : (preg_match("/(like)/i", $value) ? ' LIKE ' : ' = ') . $placeholder); } //echo $conditionSql; return $conditionSql; }
/** * Gets the conditional SQL fragment used in the WHERE clause when selecting * entities in this persister. * * Subclasses are supposed to override this method if they intend to change * or alter the criteria by which entities are selected. * * @param array $criteria * @param AssociationMapping $assoc * @return string */ protected function _getSelectConditionSQL(array $criteria, $assoc = null) { $conditionSql = ''; foreach ($criteria as $field => $value) { $conditionSql .= $conditionSql ? ' AND ' : ''; if (isset($this->_class->columnNames[$field])) { if (isset($this->_class->fieldMappings[$field]['inherited'])) { $conditionSql .= $this->_getSQLTableAlias($this->_class->fieldMappings[$field]['inherited']) . '.'; } else { $conditionSql .= $this->_getSQLTableAlias($this->_class->name) . '.'; } $conditionSql .= $this->_class->getQuotedColumnName($field, $this->_platform); } else { if ($assoc !== null) { if ($assoc->isManyToMany()) { $owningAssoc = $assoc->isOwningSide ? $assoc : $this->_em->getClassMetadata($assoc->targetEntityName)->associationMappings[$assoc->mappedBy]; $conditionSql .= $owningAssoc->getQuotedJoinTableName($this->_platform) . '.' . $field; } else { $conditionSql .= $field; } } else { throw ORMException::unrecognizedField($field); } } $conditionSql .= ' = ?'; } return $conditionSql; }
/** * Gets the SELECT SQL to select one or more entities by a set of field criteria. * * @param array $criteria * @return string The SQL. */ protected function _getSelectEntitiesSql(array &$criteria, $assoc = null) { // Construct WHERE conditions $conditionSql = ''; foreach ($criteria as $field => $value) { if ($conditionSql != '') { $conditionSql .= ' AND '; } if (isset($this->_class->columnNames[$field])) { $conditionSql .= $this->_class->getQuotedColumnName($field, $this->_platform); } else { if (isset($this->_class->fieldNames[$field])) { $conditionSql .= $this->_class->getQuotedColumnName($this->_class->fieldNames[$field], $this->_platform); } else { if ($assoc !== null) { $conditionSql .= $assoc->getQuotedJoinColumnName($field, $this->_platform); } else { throw ORMException::unrecognizedField($field); } } } $conditionSql .= ' = ?'; } return 'SELECT ' . $this->_getSelectColumnList() . ' FROM ' . $this->_class->getQuotedTableName($this->_platform) . ($conditionSql ? ' WHERE ' . $conditionSql : ''); }
/** * Gets the SELECT SQL to select one or more entities by a set of field criteria. * * @param array $criteria * @param AssociationMapping $assoc * @param string $orderBy * @return string * @override */ protected function _getSelectEntitiesSQL(array &$criteria, $assoc = null, $orderBy = null) { $idColumns = $this->_class->getIdentifierColumnNames(); $baseTableAlias = $this->_getSQLTableAlias($this->_class); if ($this->_selectColumnListSql === null) { // Add regular columns $columnList = ''; foreach ($this->_class->fieldMappings as $fieldName => $mapping) { if ($columnList != '') { $columnList .= ', '; } $columnList .= $this->_getSelectColumnSQL($fieldName, isset($mapping['inherited']) ? $this->_em->getClassMetadata($mapping['inherited']) : $this->_class); } // Add foreign key columns foreach ($this->_class->associationMappings as $assoc) { if ($assoc->isOwningSide && $assoc->isOneToOne()) { $tableAlias = isset($this->_class->inheritedAssociationFields[$assoc->sourceFieldName]) ? $this->_getSQLTableAlias($this->_em->getClassMetadata($this->_class->inheritedAssociationFields[$assoc->sourceFieldName])) : $baseTableAlias; foreach ($assoc->targetToSourceKeyColumns as $srcColumn) { $columnAlias = $srcColumn . $this->_sqlAliasCounter++; $columnList .= ", {$tableAlias}.{$srcColumn} AS {$columnAlias}"; $resultColumnName = $this->_platform->getSQLResultCasing($columnAlias); if (!isset($this->_resultColumnNames[$resultColumnName])) { $this->_resultColumnNames[$resultColumnName] = $srcColumn; } } } } // Add discriminator column (DO NOT ALIAS THIS COLUMN). $discrColumn = $this->_class->discriminatorColumn['name']; if ($this->_class->rootEntityName == $this->_class->name) { $columnList .= ", {$baseTableAlias}.{$discrColumn}"; } else { $columnList .= ', ' . $this->_getSQLTableAlias($this->_em->getClassMetadata($this->_class->rootEntityName)) . ".{$discrColumn}"; } $resultColumnName = $this->_platform->getSQLResultCasing($discrColumn); $this->_resultColumnNames[$resultColumnName] = $discrColumn; } // INNER JOIN parent tables $joinSql = ''; foreach ($this->_class->parentClasses as $parentClassName) { $parentClass = $this->_em->getClassMetadata($parentClassName); $tableAlias = $this->_getSQLTableAlias($parentClass); $joinSql .= ' INNER JOIN ' . $parentClass->getQuotedTableName($this->_platform) . ' ' . $tableAlias . ' ON '; $first = true; foreach ($idColumns as $idColumn) { if ($first) { $first = false; } else { $joinSql .= ' AND '; } $joinSql .= $baseTableAlias . '.' . $idColumn . ' = ' . $tableAlias . '.' . $idColumn; } } // OUTER JOIN sub tables foreach ($this->_class->subClasses as $subClassName) { $subClass = $this->_em->getClassMetadata($subClassName); $tableAlias = $this->_getSQLTableAlias($subClass); if ($this->_selectColumnListSql === null) { // Add subclass columns foreach ($subClass->fieldMappings as $fieldName => $mapping) { if (isset($mapping['inherited'])) { continue; } $columnList .= ', ' . $this->_getSelectColumnSQL($fieldName, $subClass); } // Add join columns (foreign keys) foreach ($subClass->associationMappings as $assoc2) { if ($assoc2->isOwningSide && $assoc2->isOneToOne() && !isset($subClass->inheritedAssociationFields[$assoc2->sourceFieldName])) { foreach ($assoc2->targetToSourceKeyColumns as $srcColumn) { $columnAlias = $srcColumn . $this->_sqlAliasCounter++; $columnList .= ', ' . $tableAlias . ".{$srcColumn} AS {$columnAlias}"; $resultColumnName = $this->_platform->getSQLResultCasing($columnAlias); if (!isset($this->_resultColumnNames[$resultColumnName])) { $this->_resultColumnNames[$resultColumnName] = $srcColumn; } } } } } // Add LEFT JOIN $joinSql .= ' LEFT JOIN ' . $subClass->getQuotedTableName($this->_platform) . ' ' . $tableAlias . ' ON '; $first = true; foreach ($idColumns as $idColumn) { if ($first) { $first = false; } else { $joinSql .= ' AND '; } $joinSql .= $baseTableAlias . '.' . $idColumn . ' = ' . $tableAlias . '.' . $idColumn; } } $conditionSql = ''; foreach ($criteria as $field => $value) { if ($conditionSql != '') { $conditionSql .= ' AND '; } if (isset($this->_class->fieldMappings[$field]['inherited'])) { $conditionSql .= $this->_getSQLTableAlias($this->_em->getClassMetadata($this->_class->fieldMappings[$field]['inherited'])) . '.'; } else { $conditionSql .= $baseTableAlias . '.'; } if (isset($this->_class->columnNames[$field])) { $conditionSql .= $this->_class->getQuotedColumnName($field, $this->_platform); } else { if ($assoc !== null) { $conditionSql .= $field; } else { throw ORMException::unrecognizedField($field); } } $conditionSql .= ' = ?'; } $orderBySql = ''; if ($orderBy !== null) { $orderBySql = $this->_getCollectionOrderBySQL($orderBy, $baseTableAlias); } if ($this->_selectColumnListSql === null) { $this->_selectColumnListSql = $columnList; } return 'SELECT ' . $this->_selectColumnListSql . ' FROM ' . $this->_class->getQuotedTableName($this->_platform) . ' ' . $baseTableAlias . $joinSql . ($conditionSql != '' ? ' WHERE ' . $conditionSql : '') . $orderBySql; }