diff --git a/src/Oro/Bundle/DataGridBundle/Extension/Sorter/PostgresqlGridModifier.php b/src/Oro/Bundle/DataGridBundle/Extension/Sorter/PostgresqlGridModifier.php new file mode 100644 index 00000000000..1678ade9e50 --- /dev/null +++ b/src/Oro/Bundle/DataGridBundle/Extension/Sorter/PostgresqlGridModifier.php @@ -0,0 +1,193 @@ +databaseDriver = $databaseDriver; + $this->entityClassResolver = $entityClassResolver; + } + + /** + * {@inheritdoc} + */ + public function isApplicable(DatagridConfiguration $config) + { + return $this->databaseDriver === DatabaseDriverInterface::DRIVER_POSTGRESQL; + } + + /** + * {@inheritDoc} + */ + public function getPriority() + { + return self::PRIORITY; + } + + /** + * Add sorting by identifier because postgresql return rows in different order on two the same sql, but + * different LIMIT number + * + * @param DatagridConfiguration $config + * @param DatasourceInterface $datasource + * @return mixed|void + */ + public function visitDatasource(DatagridConfiguration $config, DatasourceInterface $datasource) + { + //getQueryBuilder exists only in datagrid orm datasource + if (!$datasource instanceof OrmDatasource) { + return; + } + + $entityClassName = $this->getEntityClassName($config); + /** @var QueryBuilder $queryBuilder */ + $queryBuilder = $datasource->getQueryBuilder(); + + if (!$entityClassName) { + return; + } + + $fromParts = $queryBuilder->getDQLPart('from'); + $alias = false; + + $metadata = $queryBuilder->getEntityManager()->getClassMetadata($entityClassName); + $identifier = $metadata->getSingleIdentifierFieldName(); + + /** @var From $fromPart */ + foreach ($fromParts as $fromPart) { + if ($this->entityClassResolver->getEntityClass($fromPart->getFrom()) == $entityClassName) { + $alias = $fromPart->getAlias(); + break; + } + } + + if ($alias && $this->isAllowedAddingSorting($alias, $identifier, $queryBuilder)) { + $field = $alias . '.' . $identifier; + $orderBy = $queryBuilder->getDQLPart('orderBy'); + if (!isset($orderBy[$field])) { + if ($this->isDistinct($queryBuilder)) { + $this->ensureIdentifierSelected($queryBuilder, $field); + } + $queryBuilder->addOrderBy($field, 'ASC'); + } + } + } + + /** + * @param DatagridConfiguration $config + * + * @return null|string + */ + protected function getEntityClassName(DatagridConfiguration $config) + { + $entityClassName = $config->offsetGetByPath('[extended_entity_name]'); + if ($entityClassName) { + return $entityClassName; + } + + $from = $config->offsetGetByPath('[source][query][from]'); + if (count($from) !== 0) { + return $this->entityClassResolver->getEntityClass($from[0]['table']); + } + + return null; + } + + /** + * @param string $alias + * @param string $identifier + * @param QueryBuilder $queryBuilder + * @return bool + */ + protected function isAllowedAddingSorting($alias, $identifier, QueryBuilder $queryBuilder) + { + $groupByParts = $queryBuilder->getDQLPart('groupBy'); + + if (!count($groupByParts)) { + return true; + } + + foreach ($groupByParts as $groupBy) { + if (in_array($alias.'.'.$identifier, $groupBy->getParts(), true) !== false) { + return true; + } + } + + return false; + } + + /** + * @param QueryBuilder $queryBuilder + * @return bool + */ + protected function isDistinct(QueryBuilder $queryBuilder) + { + if ($queryBuilder->getDQLPart('distinct')) { + return true; + } + + foreach ($queryBuilder->getDQLPart('select') as $select) { + $selectString = ltrim(strtolower((string)$select)); + if (strpos($selectString, 'distinct ') === 0) { + return true; + } + } + + return false; + } + + /** + * @param QueryBuilder $queryBuilder + * @param string $field + */ + protected function ensureIdentifierSelected(QueryBuilder $queryBuilder, $field) + { + $isSelected = false; + /** @var Select $select */ + foreach ($queryBuilder->getDQLPart('select') as $select) { + $selectString = ltrim(strtolower((string)$select)); + if (strpos($selectString, 'distinct ') === 0) { + $selectString = substr($selectString, 9); + } + // if field itself or field with alias + if ($selectString === $field || + ( + strpos($selectString, $field) === 0 && + strpos(strtolower(ltrim(substr($selectString, strlen($field)))), 'as ') === 0 + ) + ) { + $isSelected = true; + break; + } + } + + if (!$isSelected) { + $queryBuilder->addSelect($field); + } + } +} diff --git a/src/Oro/Bundle/DataGridBundle/Extension/Sorter/PreciseOrderByExtension.php b/src/Oro/Bundle/DataGridBundle/Extension/Sorter/PreciseOrderByExtension.php deleted file mode 100644 index cbeadf7e37f..00000000000 --- a/src/Oro/Bundle/DataGridBundle/Extension/Sorter/PreciseOrderByExtension.php +++ /dev/null @@ -1,88 +0,0 @@ -queryHintResolver = $queryHintResolver; - } - - /** - * {@inheritdoc} - */ - public function getPriority() - { - // should visit after all extensions and after SorterExtension - return -261; - } - - /** - * {@inheritdoc} - */ - public function isApplicable(DatagridConfiguration $config) - { - return OrmDatasource::TYPE === $config->getDatasourceType(); - } - - /** - * {@inheritdoc} - */ - public function processConfigs(DatagridConfiguration $config) - { - $addHint = true; - $resolvedHintName = $this->queryHintResolver->resolveHintName(self::HINT_PRECISE_ORDER_BY); - $hints = $config->offsetGetByPath('[source][hints]', []); - foreach ($hints as $hintKey => $hint) { - if (is_array($hint)) { - $hintName = $this->getHintAttribute($hint, 'name'); - if (self::HINT_PRECISE_ORDER_BY === $hintName || $resolvedHintName === $hintName) { - $addHint = false; - $hintValue = $this->getHintAttribute($hint, 'value'); - if (false === $hintValue) { - // remove the hint if it was disabled - unset($hints[$hintKey]); - $config->offsetSetByPath('[source][hints]', $hints); - } - break; - } - } elseif (self::HINT_PRECISE_ORDER_BY === $hint || $resolvedHintName === $hint) { - $addHint = false; - break; - } - } - if ($addHint) { - $config->offsetAddToArrayByPath('[source][hints]', [self::HINT_PRECISE_ORDER_BY]); - } - } - - /** - * @param array $hint - * @param string $attributeName - * - * @return mixed - */ - private function getHintAttribute(array $hint, $attributeName) - { - return array_key_exists($attributeName, $hint) - ? $hint[$attributeName] - : null; - } -} diff --git a/src/Oro/Bundle/DataGridBundle/Resources/config/extensions.yml b/src/Oro/Bundle/DataGridBundle/Resources/config/extensions.yml index 0929fdaf851..eee29da9066 100644 --- a/src/Oro/Bundle/DataGridBundle/Resources/config/extensions.yml +++ b/src/Oro/Bundle/DataGridBundle/Resources/config/extensions.yml @@ -13,6 +13,7 @@ parameters: oro_datagrid.extension.totals.class: Oro\Bundle\DataGridBundle\Extension\Totals\OrmTotalsExtension oro_datagrid.extension.columns.class: Oro\Bundle\DataGridBundle\Extension\Columns\ColumnsExtension oro_datagrid.extension.mode.class: Oro\Bundle\DataGridBundle\Extension\Mode\ModeExtension + oro_datagrid.extension.postgresql_grid_modifier.class: Oro\Bundle\DataGridBundle\Extension\Sorter\PostgresqlGridModifier oro_datagrid.extension.board.class: Oro\Bundle\DataGridBundle\Extension\Board\BoardExtension oro_datagrid.extension.appearance.class: Oro\Bundle\DataGridBundle\Extension\Appearance\AppearanceExtension @@ -135,10 +136,11 @@ services: tags: - { name: oro_datagrid.extension } - oro_datagrid.extension.precise_order_by: - class: Oro\Bundle\DataGridBundle\Extension\Sorter\PreciseOrderByExtension + oro_datagrid.extension.postgresql_grid_modifier: + class: %oro_datagrid.extension.postgresql_grid_modifier.class% arguments: - - '@oro_entity.query_hint_resolver' + - %database_driver% + - '@oro_entity.orm.entity_class_resolver' tags: - { name: oro_datagrid.extension } diff --git a/src/Oro/Bundle/DataGridBundle/Resources/doc/backend/datasources/orm.md b/src/Oro/Bundle/DataGridBundle/Resources/doc/backend/datasources/orm.md index 22795c35ab6..34a313d89e1 100644 --- a/src/Oro/Bundle/DataGridBundle/Resources/doc/backend/datasources/orm.md +++ b/src/Oro/Bundle/DataGridBundle/Resources/doc/backend/datasources/orm.md @@ -22,24 +22,6 @@ datagrid: from: - { table: OroCRMContactBundle:Group, alias: g } ``` -Important notes ---------------- - -By default all datagrids that use ORM datasource is marked by [HINT_PRECISE_ORDER_BY](../../../../../../Component/DoctrineUtils/README.md#preciseorderbywalker-class) query hint. This guarantee that rows are sorted in the same way independent from a state of SQL server and from values of OFFSET and LIMIT clauses. More details you can find in [PostgreSQL documentation](https://www.postgresql.org/docs/8.1/static/queries-limit.html). - -If you need to disable this behaviour for your datagrid the following configuration can be used: - -```yaml - -datagrids: - DATAGRID_NAME_HERE: - source: - type: orm - query: - ... - hints: - - { name: HINT_PRECISE_ORDER_BY, value: false } -``` Query hints ----------- diff --git a/src/Oro/Bundle/DataGridBundle/Tests/Functional/Extension/PostgresqlGridModifierTest.php b/src/Oro/Bundle/DataGridBundle/Tests/Functional/Extension/PostgresqlGridModifierTest.php new file mode 100644 index 00000000000..a15f83369b0 --- /dev/null +++ b/src/Oro/Bundle/DataGridBundle/Tests/Functional/Extension/PostgresqlGridModifierTest.php @@ -0,0 +1,81 @@ +initClient([], $this->generateBasicAuthHeader()); + $this->client->useHashNavigation(true); + $this->container = $this->client->getKernel()->getContainer(); + $this->loadFixtures([ + 'Oro\Bundle\DataGridBundle\Tests\Functional\DataFixtures\LoadUserData', + ]); + } + + public function testGridIsValidAndContainsEntityIdentifierInSorting() + { + if ($this->container->getParameter('database_driver') !== DatabaseDriverInterface::DRIVER_POSTGRESQL) { + $this->markTestSkipped('Test runs only on PostgreSQL environment'); + } + + $getIdFunction = function ($array) { + if (isset($array['id'])) { + return $array['id']; + } + return null; + }; + + // any route just to initialize security context + $this->client->request('GET', $this->getUrl('oro_user_index')); + + $isFoundIdentifier = false; + $usersGrid = $this->container->get('oro_datagrid.datagrid.manager')->getDatagrid( + $this->gridName, + $this->gridParameters + ); + //this is just running my extension + $usersGrid->getData(); + /** @var QueryBuilder $queryBuilder */ + $queryBuilder = $usersGrid->getDatasource()->getQueryBuilder(); + $queryBuilder->setFirstResult(0)->setMaxResults(10); + $idsWithLittleLimit = array_map($getIdFunction, $queryBuilder->getQuery()->getResult()); + $queryBuilder->setFirstResult(0)->setMaxResults(50000); + $idsWithLargeLimit = array_map($getIdFunction, $queryBuilder->getQuery()->getResult()); + $orderByParts = $usersGrid->getDatasource()->getQueryBuilder()->getDQLPart('orderBy'); + + foreach ($orderByParts as $part) { + $parts = $part->getParts(); + if (in_array($this->identifier . ' ASC', $parts, true) !== false) { + $isFoundIdentifier = true; + break; + } + } + + $this->assertTrue($isFoundIdentifier); + $this->assertEquals($idsWithLargeLimit, $idsWithLittleLimit); + + // make sure query builder valid + $queryBuilder->getQuery()->execute(); + } +} diff --git a/src/Oro/Bundle/DataGridBundle/Tests/Unit/Extension/Sorter/PreciseOrderByExtensionTest.php b/src/Oro/Bundle/DataGridBundle/Tests/Unit/Extension/Sorter/PreciseOrderByExtensionTest.php deleted file mode 100644 index c12029a4e32..00000000000 --- a/src/Oro/Bundle/DataGridBundle/Tests/Unit/Extension/Sorter/PreciseOrderByExtensionTest.php +++ /dev/null @@ -1,121 +0,0 @@ -getMockBuilder(QueryHintResolver::class) - ->disableOriginalConstructor() - ->getMock(); - $queryHintResolver->expects(self::any()) - ->method('resolveHintName') - ->with(PreciseOrderByExtension::HINT_PRECISE_ORDER_BY) - ->willReturn('oro_entity.precise_order_by'); - - $this->extension = new PreciseOrderByExtension($queryHintResolver); - } - - public function testGetPriority() - { - self::assertSame(-261, $this->extension->getPriority()); - } - - public function testIsApplicableForNotOrmDatasource() - { - $config = DatagridConfiguration::create(['source' => ['type' => 'other']]); - self::assertFalse($this->extension->isApplicable($config)); - } - - public function testIsApplicableForOrmDatasource() - { - $config = DatagridConfiguration::create(['source' => ['type' => 'orm']]); - self::assertTrue($this->extension->isApplicable($config)); - } - - public function testProcessConfigsWhenNoPreciseOrderByHint() - { - $config = DatagridConfiguration::create([]); - $this->extension->processConfigs($config); - self::assertEquals( - ['HINT_PRECISE_ORDER_BY'], - $config->offsetGetByPath('[source][hints]') - ); - } - - public function testProcessConfigsWhenPreciseOrderByHintAlreadyExists() - { - $config = DatagridConfiguration::create(['source' => ['hints' => ['HINT_PRECISE_ORDER_BY']]]); - $this->extension->processConfigs($config); - self::assertEquals( - ['HINT_PRECISE_ORDER_BY'], - $config->offsetGetByPath('[source][hints]') - ); - } - - public function testProcessConfigsWhenPreciseOrderByHintAlreadyExistsAndWasAddedByItsName() - { - $config = DatagridConfiguration::create(['source' => ['hints' => ['oro_entity.precise_order_by']]]); - $this->extension->processConfigs($config); - self::assertEquals( - ['oro_entity.precise_order_by'], - $config->offsetGetByPath('[source][hints]') - ); - } - - public function testProcessConfigsWhenPreciseOrderByHintAlreadyExistsFullDeclaration() - { - $config = DatagridConfiguration::create( - ['source' => ['hints' => [['name' => 'HINT_PRECISE_ORDER_BY', 'value' => true]]]] - ); - $this->extension->processConfigs($config); - self::assertEquals( - [['name' => 'HINT_PRECISE_ORDER_BY', 'value' => true]], - $config->offsetGetByPath('[source][hints]') - ); - } - - public function testProcessConfigsWhenPreciseOrderByHintAlreadyExistsFullDeclarationAndWasAddedByItsName() - { - $config = DatagridConfiguration::create( - ['source' => ['hints' => [['name' => 'oro_entity.precise_order_by', 'value' => true]]]] - ); - $this->extension->processConfigs($config); - self::assertEquals( - [['name' => 'oro_entity.precise_order_by', 'value' => true]], - $config->offsetGetByPath('[source][hints]') - ); - } - - public function testProcessConfigsWhenPreciseOrderByHintDisabled() - { - $config = DatagridConfiguration::create( - ['source' => ['hints' => [['name' => 'HINT_PRECISE_ORDER_BY', 'value' => false]]]] - ); - $this->extension->processConfigs($config); - self::assertEquals( - [], - $config->offsetGetByPath('[source][hints]') - ); - } - - public function testProcessConfigsWhenPreciseOrderByHintDisabledByItsName() - { - $config = DatagridConfiguration::create( - ['source' => ['hints' => [['name' => 'oro_entity.precise_order_by', 'value' => false]]]] - ); - $this->extension->processConfigs($config); - self::assertEquals( - [], - $config->offsetGetByPath('[source][hints]') - ); - } -} diff --git a/src/Oro/Bundle/EmailBundle/Resources/config/datagrid.yml b/src/Oro/Bundle/EmailBundle/Resources/config/datagrid.yml index da17864847a..a0ac5aebe66 100644 --- a/src/Oro/Bundle/EmailBundle/Resources/config/datagrid.yml +++ b/src/Oro/Bundle/EmailBundle/Resources/config/datagrid.yml @@ -150,6 +150,13 @@ datagrid: - { name: oro.use_index, value: user_owner_id_mailbox_owner_id_organization_id } columns: + mailbox: + data_name: origin + label: oro.email.mailbox.entity_label + type: twig + frontend_type: html + template: OroEmailBundle:Email:Datagrid/Property/mailbox.html.twig + renderable: false contacts: data_name: email.contacts type: twig @@ -168,6 +175,7 @@ datagrid: label: frontend_type: html template: OroEmailBundle:Email:Datagrid/Property/attachments.html.twig + manageable: false receivedAt: data_name: receivedAt type: twig @@ -180,6 +188,7 @@ datagrid: columns: subject: { data_name: e.subject } receivedAt: { data_name: receivedAt } + mailbox: { data_name: eu.origin } default: { receivedAt: %oro_datagrid.extension.orm_sorter.class%::DIRECTION_DESC } options: entityHint: email @@ -302,8 +311,6 @@ datagrid: label: oro.email.datagrid.emails.action.mark_as_unread icon: minus options: - toolbarOptions: - addColumnManager: false entity_pagination: true entity_pagination_target: Oro\Bundle\EmailBundle\Entity\Email diff --git a/src/Oro/Bundle/EmailBundle/Resources/translations/messages.en.yml b/src/Oro/Bundle/EmailBundle/Resources/translations/messages.en.yml index a0673273a90..98fd85ca3c9 100644 --- a/src/Oro/Bundle/EmailBundle/Resources/translations/messages.en.yml +++ b/src/Oro/Bundle/EmailBundle/Resources/translations/messages.en.yml @@ -10,6 +10,7 @@ oro: email: imap.folder.checkAll: All + mailbox_name.personal: Personal autocomplete: recently_used: Recently used contexts: Contexts diff --git a/src/Oro/Bundle/EmailBundle/Resources/views/Email/Datagrid/Property/mailbox.html.twig b/src/Oro/Bundle/EmailBundle/Resources/views/Email/Datagrid/Property/mailbox.html.twig new file mode 100644 index 00000000000..45e87c15644 --- /dev/null +++ b/src/Oro/Bundle/EmailBundle/Resources/views/Email/Datagrid/Property/mailbox.html.twig @@ -0,0 +1,11 @@ +{% set origin = record.getValue('origin') %} +{% set mailboxName = record.getValue('origin.mailboxName') %} +{% set mailbox = record.getValue('origin.mailbox') %} +{% if mailbox is not null %} + {% set mailboxName = mailbox.label %} +{% elseif oro_class_name(origin) != 'Oro\\Bundle\\EmailBundle\\Entity\\InternalEmailOrigin' %} + {% set mailboxName = 'oro.email.mailbox_name.personal'|trans %} +{% endif %} + + {{ mailboxName }} + diff --git a/src/Oro/Bundle/EntityBundle/Resources/config/orm.yml b/src/Oro/Bundle/EntityBundle/Resources/config/orm.yml index 5f950a37b3c..7159dd33eee 100644 --- a/src/Oro/Bundle/EntityBundle/Resources/config/orm.yml +++ b/src/Oro/Bundle/EntityBundle/Resources/config/orm.yml @@ -49,13 +49,3 @@ services: class: %oro_entity.orm.insert_from_select_query_executor.class% arguments: - '@oro_entity.orm.native_query_executor_helper' - - oro_entity.query_hint.precise_order_by: - public: false - abstract: true - tags: - - - name: oro_entity.query_hint - hint: oro_entity.precise_order_by - alias: HINT_PRECISE_ORDER_BY - tree_walker: Oro\Component\DoctrineUtils\ORM\Walker\PreciseOrderByWalker diff --git a/src/Oro/Bundle/ImapBundle/Connector/ImapMessageIterator.php b/src/Oro/Bundle/ImapBundle/Connector/ImapMessageIterator.php index 653a670cd08..b3e46c13b2a 100644 --- a/src/Oro/Bundle/ImapBundle/Connector/ImapMessageIterator.php +++ b/src/Oro/Bundle/ImapBundle/Connector/ImapMessageIterator.php @@ -208,6 +208,8 @@ protected function initialize() $this->iterationMin = 0; $this->iterationMax = count($this->ids) - 1; } + + $this->imap->clearCacheUniqueId(); } /** diff --git a/src/Oro/Bundle/ImapBundle/Mail/Storage/Imap.php b/src/Oro/Bundle/ImapBundle/Mail/Storage/Imap.php index 13fb0ca4d34..246b9fe9a52 100644 --- a/src/Oro/Bundle/ImapBundle/Mail/Storage/Imap.php +++ b/src/Oro/Bundle/ImapBundle/Mail/Storage/Imap.php @@ -68,6 +68,13 @@ class Imap extends \Zend\Mail\Storage\Imap */ private $ignoreCloseCommand = false; + /** + * It is used to cache response from getUniqueId in getNumberByUniqueId + * + * @var array + */ + private $uniqueIds = []; + /** * {@inheritdoc} * @SuppressWarnings(PHPMD.NPathComplexity) @@ -387,6 +394,34 @@ public function close() parent::close(); } + /** + * {@inheritdoc} + */ + public function getNumberByUniqueId($id) + { + if (!$this->uniqueIds) { + $uniqueIds = $this->getUniqueId(); + if (is_array($uniqueIds)) { + $this->uniqueIds = $uniqueIds; + } + } + foreach ($this->uniqueIds as $k => $v) { + if ($v == $id) { + return $k; + } + } + + throw new BaseException\InvalidArgumentException('unique id not found'); + } + + /** + * Clear cache of UniqueId which was created in method getNumberByUniqueId + */ + public function clearCacheUniqueId() + { + $this->uniqueIds = []; + } + /** * Creates Message object based on the given data * diff --git a/src/Oro/Bundle/ImapBundle/Tests/Unit/Mail/Storage/ImapTest.php b/src/Oro/Bundle/ImapBundle/Tests/Unit/Mail/Storage/ImapTest.php new file mode 100644 index 00000000000..cf60159a88e --- /dev/null +++ b/src/Oro/Bundle/ImapBundle/Tests/Unit/Mail/Storage/ImapTest.php @@ -0,0 +1,78 @@ + 1, + 2 => 2, + 3 => 3, + 4 => 4, + 5 => 5 + ]; + + $protocolImap = $this->getMockBuilder('Oro\Bundle\ImapBundle\Mail\Protocol\Imap') + ->disableOriginalConstructor()->getMock(); + $protocolImap->expects(self::once())->method('select')->willReturn(['uidvalidity'=>'']); + $protocolImap->expects(self::once())->method('fetch')->willReturn($ids); + + $imap = new Imap($protocolImap); + + $id = '3'; + self::assertEquals(3, $imap->getNumberByUniqueId($id)); + + $protocolImap->expects(self::never())->method('fetch'); + self::assertEquals(3, $imap->getNumberByUniqueId($id)); + } + + /** + * @expectedException InvalidArgumentException + * @expectedExceptionMessage unique id not found + */ + public function testExceptionForGetNumberByUniqueId() + { + $ids = [ + 1 => 1, + 2 => 2, + 3 => 3, + 4 => 4, + 5 => 5 + ]; + + $protocolImap = $this->getMockBuilder('Oro\Bundle\ImapBundle\Mail\Protocol\Imap') + ->disableOriginalConstructor()->getMock(); + $protocolImap->expects(self::once())->method('select')->willReturn(['uidvalidity'=>'']); + $protocolImap->expects(self::once())->method('fetch')->willReturn($ids); + + $imap = new Imap($protocolImap); + + $id = '6'; + $imap->getNumberByUniqueId($id); + } + + /** + * @expectedException InvalidArgumentException + * @expectedExceptionMessage unique id not found + */ + public function testCacheForGetNumberByUniqueIdNotArray() + { + $ids = 3; + + $protocolImap = $this->getMockBuilder('Oro\Bundle\ImapBundle\Mail\Protocol\Imap') + ->disableOriginalConstructor()->getMock(); + $protocolImap->expects(self::once())->method('select')->willReturn(['uidvalidity'=>'']); + $protocolImap->expects(self::once())->method('fetch')->willReturn($ids); + + $imap = new Imap($protocolImap); + + $id = '3'; + $imap->getNumberByUniqueId($id); + } +} diff --git a/src/Oro/Bundle/SecurityBundle/ORM/Walker/CurrentUserWalker.php b/src/Oro/Bundle/SecurityBundle/ORM/Walker/CurrentUserWalker.php index 009894fb490..6ad385c0860 100644 --- a/src/Oro/Bundle/SecurityBundle/ORM/Walker/CurrentUserWalker.php +++ b/src/Oro/Bundle/SecurityBundle/ORM/Walker/CurrentUserWalker.php @@ -13,6 +13,8 @@ class CurrentUserWalker extends TreeWalkerAdapter { const HINT_SECURITY_CONTEXT = 'oro_security.current_user_walker.security_context'; + const EXPECTED_TYPE = 12; + /** * {@inheritdoc} */ @@ -123,7 +125,7 @@ protected function createSimpleConditionalExpression($expr) */ protected function createEqualByIdComparisonExpression($alias, $field, $id) { - $pathExpr = new AST\PathExpression(AST\PathExpression::TYPE_SINGLE_VALUED_ASSOCIATION, $alias, $field); + $pathExpr = new AST\PathExpression(self::EXPECTED_TYPE, $alias, $field); $pathExpr->type = AST\PathExpression::TYPE_SINGLE_VALUED_ASSOCIATION; return new AST\ComparisonExpression( diff --git a/src/Oro/Component/DoctrineUtils/ORM/QueryHintResolver.php b/src/Oro/Component/DoctrineUtils/ORM/QueryHintResolver.php index 5779ec01ab3..0436c371a81 100644 --- a/src/Oro/Component/DoctrineUtils/ORM/QueryHintResolver.php +++ b/src/Oro/Component/DoctrineUtils/ORM/QueryHintResolver.php @@ -152,7 +152,7 @@ public function addHints(Query $query, array $hints) * * @return string */ - public function resolveHintName($name) + protected function resolveHintName($name) { if (isset($this->aliases[$name])) { return $this->aliases[$name]; diff --git a/src/Oro/Component/DoctrineUtils/ORM/Walker/PreciseOrderByWalker.php b/src/Oro/Component/DoctrineUtils/ORM/Walker/PreciseOrderByWalker.php deleted file mode 100644 index 971749e15ab..00000000000 --- a/src/Oro/Component/DoctrineUtils/ORM/Walker/PreciseOrderByWalker.php +++ /dev/null @@ -1,308 +0,0 @@ -fromClause->identificationVariableDeclarations as $declaration) { - if ($declaration->rangeVariableDeclaration->isRoot) { - $rootEntityClass = $declaration->rangeVariableDeclaration->abstractSchemaName; - $rootEntityAlias = $declaration->rangeVariableDeclaration->aliasIdentificationVariable; - break; - } - } - if ($rootEntityClass && $rootEntityAlias) { - $this->updateQuery($AST, $rootEntityClass, $rootEntityAlias); - } - } - - /** - * @param AST\SelectStatement $AST - * @param $rootEntityClass - * @param $rootEntityAlias - */ - private function updateQuery(AST\SelectStatement $AST, $rootEntityClass, $rootEntityAlias) - { - $orderByClause = $AST->orderByClause; - if (null === $orderByClause) { - $orderByClause = new AST\OrderByClause([]); - } - /** @var AST\OrderByItem[] $itemsToAdd */ - $itemsToAdd = []; - $fieldNamesToCheck = $this->getIdentifierFieldNames($rootEntityClass); - if (null !== $AST->groupByClause && !empty($AST->groupByClause->groupByItems)) { - $fieldNamesToCheck = $this->processGroupBy( - $AST->groupByClause, - $rootEntityAlias, - $fieldNamesToCheck, - $AST->selectClause - ); - } - $direction = $this->getOrderByDirection($orderByClause); - foreach ($fieldNamesToCheck as $fieldName) { - if (!$this->hasOrderByField($orderByClause, $rootEntityAlias, $fieldName, $AST->selectClause)) { - $itemsToAdd[] = $this->createOrderByItem($rootEntityAlias, $fieldName, $direction); - } - } - if (!empty($itemsToAdd)) { - foreach ($itemsToAdd as $item) { - $orderByClause->orderByItems[] = $item; - /** @var AST\PathExpression $expr */ - $expr = $item->expression; - if ($AST->selectClause->isDistinct) { - $this->ensureFieldExistsInSelect( - $AST->selectClause, - $expr->identificationVariable, - $expr->field - ); - } - } - if (null === $AST->orderByClause && !empty($orderByClause->orderByItems)) { - $AST->orderByClause = $orderByClause; - } - } - } - - /** - * @param AST\GroupByClause $groupByClause - * @param string $rootEntityAlias - * @param string[] $fieldNamesToCheck - * @param AST\SelectClause $selectClause - * - * @return string[] - */ - private function processGroupBy( - AST\GroupByClause $groupByClause, - $rootEntityAlias, - array $fieldNamesToCheck, - AST\SelectClause $selectClause - ) { - $fieldNamesToAdd = []; - foreach ($groupByClause->groupByItems as $groupByItem) { - foreach ($fieldNamesToCheck as $fieldName) { - if ($this->isExpressionByField($groupByItem, $rootEntityAlias, $fieldName, $selectClause)) { - $fieldNamesToAdd[] = $fieldName; - } - } - } - - return $fieldNamesToAdd; - } - - /** - * @param AST\SelectClause $selectClause - * @param string $entityAlias - * @param string $fieldName - */ - private function ensureFieldExistsInSelect(AST\SelectClause $selectClause, $entityAlias, $fieldName) - { - if (!$this->hasSelectField($selectClause, $entityAlias, $fieldName)) { - $selectClause->selectExpressions[] = $this->createHiddenSelectExpression( - $entityAlias, - $fieldName - ); - } - } - - /** - * @param string $entityClass - * - * @return string[] - */ - private function getIdentifierFieldNames($entityClass) - { - return $this->_getQuery() - ->getEntityManager() - ->getClassMetadata($entityClass) - ->getIdentifierFieldNames(); - } - - /** - * @param mixed $expr - * @param string $entityAlias - * @param string $fieldName - * @param AST\SelectClause $selectClause - * - * @return bool - */ - private function isExpressionByField($expr, $entityAlias, $fieldName, AST\SelectClause $selectClause) - { - if ($expr instanceof AST\PathExpression) { - return $this->isPathExpressionByField($expr, $entityAlias, $fieldName); - } elseif (is_string($expr)) { - /** @var AST\SelectExpression $selectExpr */ - foreach ($selectClause->selectExpressions as $selectExpr) { - if ($expr === $selectExpr->fieldIdentificationVariable) { - return $selectExpr->expression instanceof AST\PathExpression - ? $this->isPathExpressionByField($selectExpr->expression, $entityAlias, $fieldName) - : false; - } - } - } - - return false; - } - - /** - * @param AST\PathExpression $expr - * @param string $entityAlias - * @param string $fieldName - * - * @return bool - */ - private function isPathExpressionByField(AST\PathExpression $expr, $entityAlias, $fieldName) - { - return - AST\PathExpression::TYPE_STATE_FIELD === $expr->type - && $entityAlias === $expr->identificationVariable - && $fieldName === $expr->field; - } - - /** - * @param AST\SelectClause $selectClause - * @param string $entityAlias - * @param string $fieldName - * - * @return bool - */ - private function hasSelectField( - AST\SelectClause $selectClause, - $entityAlias, - $fieldName - ) { - $result = false; - /** @var AST\SelectExpression $selectExpr */ - foreach ($selectClause->selectExpressions as $selectExpr) { - if ($selectExpr->expression instanceof AST\PathExpression) { - if ($this->isPathExpressionByField($selectExpr->expression, $entityAlias, $fieldName)) { - $result = true; - break; - } - } elseif (null === $selectExpr->fieldIdentificationVariable) { - if ($selectExpr->expression instanceof AST\PartialObjectExpression) { - if ($entityAlias === $selectExpr->expression->identificationVariable - && in_array($fieldName, $selectExpr->expression->partialFieldSet, true) - ) { - $result = true; - break; - } - } elseif (is_string($selectExpr->expression) && $entityAlias = $selectExpr->expression) { - $result = true; - break; - } - } - } - - return $result; - } - - /** - * @param AST\OrderByClause $orderByClause - * @param string $entityAlias - * @param string $fieldName - * @param AST\SelectClause $selectClause - * - * @return bool - */ - private function hasOrderByField( - AST\OrderByClause $orderByClause, - $entityAlias, - $fieldName, - AST\SelectClause $selectClause - ) { - $result = false; - /** @var AST\OrderByItem $orderByItem */ - foreach ($orderByClause->orderByItems as $orderByItem) { - if ($this->isExpressionByField($orderByItem->expression, $entityAlias, $fieldName, $selectClause)) { - $result = true; - break; - } - } - - return $result; - } - - /** - * @param AST\OrderByClause $orderByClause - * - * @return string - */ - private function getOrderByDirection(AST\OrderByClause $orderByClause) - { - $direction = 'ASC'; - if (!empty($orderByClause->orderByItems)) { - /** @var AST\OrderByItem $lastOrderByItem */ - $lastOrderByItem = end($orderByClause->orderByItems); - if ($lastOrderByItem->isDesc()) { - $direction = 'DESC'; - } - } - - return $direction; - } - - /** - * @param string $entityAlias - * @param string $fieldName - * - * @return AST\SelectExpression - */ - private function createHiddenSelectExpression($entityAlias, $fieldName) - { - return new AST\SelectExpression( - $this->createFieldPathExpression($entityAlias, $fieldName), - null, - true - ); - } - - /** - * @param string $entityAlias - * @param string $fieldName - * @param string $direction - * - * @return AST\OrderByItem - */ - private function createOrderByItem($entityAlias, $fieldName, $direction = 'ASC') - { - $orderByItem = new AST\OrderByItem( - $this->createFieldPathExpression($entityAlias, $fieldName) - ); - $orderByItem->type = $direction; - - return $orderByItem; - } - - /** - * @param string $entityAlias - * @param string $fieldName - * - * @return AST\PathExpression - */ - private function createFieldPathExpression($entityAlias, $fieldName) - { - $expr = new AST\PathExpression(AST\PathExpression::TYPE_STATE_FIELD, $entityAlias, $fieldName); - $expr->type = AST\PathExpression::TYPE_STATE_FIELD; - - return $expr; - } -} diff --git a/src/Oro/Component/DoctrineUtils/README.md b/src/Oro/Component/DoctrineUtils/README.md index c656b6bce95..1084b6a2478 100644 --- a/src/Oro/Component/DoctrineUtils/README.md +++ b/src/Oro/Component/DoctrineUtils/README.md @@ -15,14 +15,3 @@ The [QueryHintResolver](./ORM/QueryHintResolver.php) can be used to make [Doctri - **resolveHints** - Resolves query hints. - **addHint** - Adds a hint to a query object. - **addHints** - Adds hints to a query object. - -PreciseOrderByWalker class --------------------------- -**Description:** -The [PreciseOrderByWalker](./ORM/Walker/PreciseOrderByWalker.php) is an [Doctrine tree walker](http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/cookbook/dql-custom-walkers.html) that is used to modify ORDER BY clause of a query to make sure that records will be returned in the same order independent from a state of SQL server and from values of OFFSET and LIMIT clauses. This is achieved by adding the primary key column of the first root entity to the end of ORDER BY clause. - -Example of usage: - -```php -$query->setHint(Query::HINT_CUSTOM_TREE_WALKERS, [PreciseOrderByWalker::class]); -``` diff --git a/src/Oro/Component/DoctrineUtils/Tests/Unit/Fixtures/Entity/Person.php b/src/Oro/Component/DoctrineUtils/Tests/Unit/Fixtures/Entity/Person.php index 7aee6e3975e..e702c74ad81 100644 --- a/src/Oro/Component/DoctrineUtils/Tests/Unit/Fixtures/Entity/Person.php +++ b/src/Oro/Component/DoctrineUtils/Tests/Unit/Fixtures/Entity/Person.php @@ -17,13 +17,6 @@ class Person */ protected $id; - /** - * @var string - * - * @ORM\Column(type="string") - */ - protected $name; - /** * @var Item * diff --git a/src/Oro/Component/DoctrineUtils/Tests/Unit/ORM/PreciseOrderByWalkerTest.php b/src/Oro/Component/DoctrineUtils/Tests/Unit/ORM/PreciseOrderByWalkerTest.php deleted file mode 100644 index a59d5b4e15f..00000000000 --- a/src/Oro/Component/DoctrineUtils/Tests/Unit/ORM/PreciseOrderByWalkerTest.php +++ /dev/null @@ -1,225 +0,0 @@ -em = $this->getTestEntityManager(); - $this->em->getConfiguration()->setMetadataDriverImpl($metadataDriver); - $this->em->getConfiguration()->setEntityNamespaces( - [ - 'Test' => 'Oro\Component\DoctrineUtils\Tests\Unit\Fixtures\Entity' - ] - ); - } - - /** - * @dataProvider queryModificationProvider - */ - public function testQueryModification($dql, $expectedSql) - { - $query = $this->em->createQuery($dql); - $query->setHint(Query::HINT_CUSTOM_TREE_WALKERS, [PreciseOrderByWalker::class]); - - $this->assertEquals($expectedSql, $query->getSQL()); - } - - /** - * @return array - * @SuppressWarnings(PHPMD.ExcessiveMethodLength) - */ - public function queryModificationProvider() - { - return [ - 'no ORDER BY' => [ - 'SELECT p.id as pId FROM Test:Person p', - 'SELECT p0_.id AS id_0 FROM Person p0_ ORDER BY p0_.id ASC', - ], - 'ORDER BY by PK' => [ - 'SELECT p.id as pId FROM Test:Person p ORDER BY p.id', - 'SELECT p0_.id AS id_0 FROM Person p0_ ORDER BY p0_.id ASC', - ], - 'ORDER BY by PK (DESC)' => [ - 'SELECT p.id as pId FROM Test:Person p ORDER BY p.id DESC', - 'SELECT p0_.id AS id_0 FROM Person p0_ ORDER BY p0_.id DESC', - ], - 'ORDER BY by PK (several fields)' => [ - 'SELECT p.id as pId FROM Test:Person p ORDER BY p.id, p.name', - 'SELECT p0_.id AS id_0 FROM Person p0_ ORDER BY p0_.id ASC, p0_.name ASC', - ], - 'ORDER BY by not PK' => [ - 'SELECT p.id as pId FROM Test:Person p ORDER BY p.name', - 'SELECT p0_.id AS id_0 FROM Person p0_ ORDER BY p0_.name ASC, p0_.id ASC', - ], - 'ORDER BY by PK alias' => [ - 'SELECT p.id as pId FROM Test:Person p ORDER BY pId', - 'SELECT p0_.id AS id_0 FROM Person p0_ ORDER BY id_0 ASC', - ], - 'ORDER BY by not PK alias' => [ - 'SELECT p.id as pId, p.name as pName FROM Test:Person p ORDER BY pName', - 'SELECT p0_.id AS id_0, p0_.name AS name_1 FROM Person p0_ ORDER BY name_1 ASC, p0_.id ASC', - ], - 'ORDER BY by association PK' => [ - 'SELECT p.name as pName FROM Test:Person p INNER JOIN p.bestItem bi ORDER BY bi.id', - 'SELECT p0_.name AS name_0 FROM Person p0_ INNER JOIN Item i1_ ON p0_.bestItem_id = i1_.id' - . ' ORDER BY i1_.id ASC, p0_.id ASC', - ], - 'ORDER BY by unidirectional association PK' => [ - 'SELECT p.name as pName FROM Test:Person p INNER JOIN Test:Item bi WITH bi = p.bestItem' - . ' ORDER BY bi.id', - 'SELECT p0_.name AS name_0 FROM Person p0_ INNER JOIN Item i1_ ON (i1_.id = p0_.bestItem_id)' - . ' ORDER BY i1_.id ASC, p0_.id ASC', - ], - 'GROUP BY by PK' => [ - 'SELECT p.id as pId, COUNT(p.name) FROM Test:Person p GROUP BY p.id', - 'SELECT p0_.id AS id_0, COUNT(p0_.name) AS sclr_1 FROM Person p0_ GROUP BY p0_.id' - . ' ORDER BY p0_.id ASC', - ], - 'GROUP BY by not PK' => [ - 'SELECT p.name as pName, COUNT(p.id) FROM Test:Person p GROUP BY p.name', - 'SELECT p0_.name AS name_0, COUNT(p0_.id) AS sclr_1 FROM Person p0_ GROUP BY p0_.name', - ], - 'GROUP BY by PK alias' => [ - 'SELECT p.id as pId, COUNT(p.name) FROM Test:Person p GROUP BY pId', - 'SELECT p0_.id AS id_0, COUNT(p0_.name) AS sclr_1 FROM Person p0_ GROUP BY p0_.id' - . ' ORDER BY p0_.id ASC', - ], - 'GROUP BY by not PK alias' => [ - 'SELECT p.name as pName, COUNT(p.id) FROM Test:Person p GROUP BY pName', - 'SELECT p0_.name AS name_0, COUNT(p0_.id) AS sclr_1 FROM Person p0_ GROUP BY p0_.name', - ], - 'GROUP BY by association PK' => [ - 'SELECT p.id as pId, COUNT(p.id) FROM Test:Person p INNER JOIN p.bestItem bi GROUP BY bi.id', - 'SELECT p0_.id AS id_0, COUNT(p0_.id) AS sclr_1 FROM Person p0_' - . ' INNER JOIN Item i1_ ON p0_.bestItem_id = i1_.id' - . ' GROUP BY i1_.id', - ], - 'GROUP BY by unidirectional association PK' => [ - 'SELECT p.id as pId, COUNT(p.id) FROM Test:Person p INNER JOIN Test:Item bi WITH bi = p.bestItem' - . ' GROUP BY bi.id', - 'SELECT p0_.id AS id_0, COUNT(p0_.id) AS sclr_1 FROM Person p0_' - . ' INNER JOIN Item i1_ ON (i1_.id = p0_.bestItem_id)' - . ' GROUP BY i1_.id', - ], - 'DISTINCT, no ORDER BY, PK in SELECT' => [ - 'SELECT DISTINCT p.id as pId FROM Test:Person p', - 'SELECT DISTINCT p0_.id AS id_0 FROM Person p0_ ORDER BY p0_.id ASC', - ], - 'DISTINCT, no ORDER BY, no PK in SELECT' => [ - 'SELECT DISTINCT p.name as pName FROM Test:Person p', - 'SELECT DISTINCT p0_.name AS name_0, p0_.id AS id_1 FROM Person p0_ ORDER BY p0_.id ASC', - ], - 'DISTINCT, ORDER BY by PK, PK in SELECT' => [ - 'SELECT DISTINCT p.id as pId FROM Test:Person p ORDER BY p.id', - 'SELECT DISTINCT p0_.id AS id_0 FROM Person p0_ ORDER BY p0_.id ASC', - ], - 'DISTINCT, ORDER BY by PK, no PK in SELECT' => [ - 'SELECT DISTINCT p.name as pName FROM Test:Person p ORDER BY p.id', - 'SELECT DISTINCT p0_.name AS name_0 FROM Person p0_ ORDER BY p0_.id ASC', - ], - 'DISTINCT, ORDER BY by not PK, PK in SELECT' => [ - 'SELECT DISTINCT p.id as pId FROM Test:Person p ORDER BY p.name', - 'SELECT DISTINCT p0_.id AS id_0 FROM Person p0_ ORDER BY p0_.name ASC, p0_.id ASC', - ], - 'DISTINCT, ORDER BY by not PK, no PK in SELECT' => [ - 'SELECT DISTINCT p.name as pName FROM Test:Person p ORDER BY p.name', - 'SELECT DISTINCT p0_.name AS name_0, p0_.id AS id_1 FROM Person p0_' - . ' ORDER BY p0_.name ASC, p0_.id ASC', - ], - 'whole entity in SELECT, no ORDER BY' => [ - 'SELECT p FROM Test:Person p', - 'SELECT p0_.id AS id_0, p0_.name AS name_1, p0_.bestItem_id AS bestItem_id_2' - . ' FROM Person p0_ ORDER BY p0_.id ASC', - ], - 'whole entity in SELECT, join, no ORDER BY' => [ - 'SELECT bi, p FROM Test:Person p INNER JOIN p.bestItem bi', - 'SELECT p0_.id AS id_0, p0_.name AS name_1, i1_.id AS id_2,' - . ' p0_.bestItem_id AS bestItem_id_3, i1_.owner_id AS owner_id_4' - . ' FROM Person p0_ INNER JOIN Item i1_ ON p0_.bestItem_id = i1_.id' - . ' ORDER BY p0_.id ASC', - ], - 'whole entity in SELECT, ORDER BY by PK' => [ - 'SELECT p FROM Test:Person p ORDER BY p.id', - 'SELECT p0_.id AS id_0, p0_.name AS name_1, p0_.bestItem_id AS bestItem_id_2' - . ' FROM Person p0_ ORDER BY p0_.id ASC', - ], - 'whole entity in SELECT, join, ORDER BY by PK' => [ - 'SELECT bi, p FROM Test:Person p INNER JOIN p.bestItem bi ORDER BY p.id', - 'SELECT p0_.id AS id_0, p0_.name AS name_1, i1_.id AS id_2,' - . ' p0_.bestItem_id AS bestItem_id_3, i1_.owner_id AS owner_id_4' - . ' FROM Person p0_ INNER JOIN Item i1_ ON p0_.bestItem_id = i1_.id' - . ' ORDER BY p0_.id ASC', - ], - 'whole entity in SELECT, join, ORDER BY by join PK' => [ - 'SELECT bi, p FROM Test:Person p INNER JOIN p.bestItem bi ORDER BY bi.id', - 'SELECT p0_.id AS id_0, p0_.name AS name_1, i1_.id AS id_2,' - . ' p0_.bestItem_id AS bestItem_id_3, i1_.owner_id AS owner_id_4' - . ' FROM Person p0_ INNER JOIN Item i1_ ON p0_.bestItem_id = i1_.id' - . ' ORDER BY i1_.id ASC, p0_.id ASC', - ], - 'whole entity in SELECT, DISTINCT, no ORDER BY' => [ - 'SELECT DISTINCT p FROM Test:Person p', - 'SELECT DISTINCT p0_.id AS id_0, p0_.name AS name_1, p0_.bestItem_id AS bestItem_id_2' - . ' FROM Person p0_ ORDER BY p0_.id ASC', - ], - 'whole entity in SELECT, DISTINCT, join, no ORDER BY' => [ - 'SELECT DISTINCT bi, p FROM Test:Person p INNER JOIN p.bestItem bi', - 'SELECT DISTINCT p0_.id AS id_0, p0_.name AS name_1, i1_.id AS id_2,' - . ' p0_.bestItem_id AS bestItem_id_3, i1_.owner_id AS owner_id_4' - . ' FROM Person p0_ INNER JOIN Item i1_ ON p0_.bestItem_id = i1_.id' - . ' ORDER BY p0_.id ASC', - ], - 'whole entity in SELECT, DISTINCT, ORDER BY by PK' => [ - 'SELECT DISTINCT p FROM Test:Person p ORDER BY p.id', - 'SELECT DISTINCT p0_.id AS id_0, p0_.name AS name_1, p0_.bestItem_id AS bestItem_id_2' - . ' FROM Person p0_ ORDER BY p0_.id ASC', - ], - 'whole entity in SELECT, DISTINCT, join, ORDER BY by PK' => [ - 'SELECT DISTINCT bi, p FROM Test:Person p INNER JOIN p.bestItem bi ORDER BY p.id', - 'SELECT DISTINCT p0_.id AS id_0, p0_.name AS name_1, i1_.id AS id_2,' - . ' p0_.bestItem_id AS bestItem_id_3, i1_.owner_id AS owner_id_4' - . ' FROM Person p0_ INNER JOIN Item i1_ ON p0_.bestItem_id = i1_.id' - . ' ORDER BY p0_.id ASC', - ], - 'whole entity in SELECT, DISTINCT, join, ORDER BY by join PK' => [ - 'SELECT DISTINCT bi, p FROM Test:Person p INNER JOIN p.bestItem bi ORDER BY bi.id', - 'SELECT DISTINCT p0_.id AS id_0, p0_.name AS name_1, i1_.id AS id_2,' - . ' p0_.bestItem_id AS bestItem_id_3, i1_.owner_id AS owner_id_4' - . ' FROM Person p0_ INNER JOIN Item i1_ ON p0_.bestItem_id = i1_.id' - . ' ORDER BY i1_.id ASC, p0_.id ASC', - ], - 'partial SELECT, no ORDER BY' => [ - 'SELECT partial p.{id} FROM Test:Person p', - 'SELECT p0_.id AS id_0, p0_.bestItem_id AS bestItem_id_1 FROM Person p0_ ORDER BY p0_.id ASC', - ], - 'partial SELECT, ORDER BY by PK' => [ - 'SELECT partial p.{id} FROM Test:Person p ORDER BY p.id', - 'SELECT p0_.id AS id_0, p0_.bestItem_id AS bestItem_id_1 FROM Person p0_ ORDER BY p0_.id ASC', - ], - 'partial SELECT, DISTINCT, no ORDER BY' => [ - 'SELECT DISTINCT partial p.{id} FROM Test:Person p', - 'SELECT DISTINCT p0_.id AS id_0, p0_.bestItem_id AS bestItem_id_1' - . ' FROM Person p0_ ORDER BY p0_.id ASC', - ], - ]; - } -} diff --git a/src/Oro/Component/DoctrineUtils/Tests/Unit/ORM/QueryHintResolverTest.php b/src/Oro/Component/DoctrineUtils/Tests/Unit/ORM/QueryHintResolverTest.php index c0a0da1bc6d..ec52996940c 100644 --- a/src/Oro/Component/DoctrineUtils/Tests/Unit/ORM/QueryHintResolverTest.php +++ b/src/Oro/Component/DoctrineUtils/Tests/Unit/ORM/QueryHintResolverTest.php @@ -212,40 +212,6 @@ public function testResolveHints() ); } - public function testResolveCustomHintName() - { - $this->queryHintResolver->addTreeWalker('test', 'Test\Walker', null, 'HINT_TEST'); - - $this->assertEquals( - 'test', - $this->queryHintResolver->resolveHintName('HINT_TEST') - ); - $this->assertEquals( - 'test', - $this->queryHintResolver->resolveHintName('test') - ); - } - - public function testResolveDoctrineHintName() - { - $this->assertEquals( - Query::HINT_CUSTOM_OUTPUT_WALKER, - $this->queryHintResolver->resolveHintName('HINT_CUSTOM_OUTPUT_WALKER') - ); - $this->assertEquals( - Query::HINT_CUSTOM_OUTPUT_WALKER, - $this->queryHintResolver->resolveHintName(Query::HINT_CUSTOM_OUTPUT_WALKER) - ); - } - - public function testResolveUndefinedHintName() - { - $this->assertEquals( - 'HINT_UNDEFINED', - $this->queryHintResolver->resolveHintName('HINT_UNDEFINED') - ); - } - /** * @return Query */