Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[All Bundles] Added PostgreSQL support #2811

Closed
wants to merge 13 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 15 additions & 14 deletions src/Kunstmaan/AdminBundle/Helper/Security/Acl/AclHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -147,9 +147,9 @@ public function apply(QueryBuilder $queryBuilder, PermissionDefinition $permissi
private function getPermittedAclIdsSQLForUser(Query $query)
{
$aclConnection = $this->em->getConnection();
$databasePrefix = is_file($aclConnection->getDatabase()) ? '' : $aclConnection->getDatabase().'.';
$stringQuoteChar = $aclConnection->getDatabasePlatform()->getStringLiteralQuoteCharacter();
$mask = $query->getHint('acl.mask');
$rootEntity = '"' . str_replace('\\', '\\\\', $query->getHint('acl.root.entity')) . '"';
$rootEntity = $stringQuoteChar . $query->getHint('acl.root.entity') . $stringQuoteChar;

/* @var $token TokenInterface */
$token = $this->tokenStorage->getToken();
Expand All @@ -166,40 +166,41 @@ private function getPermittedAclIdsSQLForUser(Query $query)
}

// Security context does not provide anonymous role automatically.
$uR = array('"IS_AUTHENTICATED_ANONYMOUSLY"');
$uR = array($stringQuoteChar . 'IS_AUTHENTICATED_ANONYMOUSLY' . $stringQuoteChar);

foreach ($userRoles as $role) {
// The reason we ignore this is because by default FOSUserBundle adds ROLE_USER for every user
if (is_string($role)) {
if ($role !== 'ROLE_USER') {
$uR[] = '"' . $role . '"';
$uR[] = $stringQuoteChar . $role . $stringQuoteChar;
}
} else {
// Symfony 3.4 compatibility
if ($role->getRole() !== 'ROLE_USER') {
$uR[] = '"' . $role->getRole() . '"';
$uR[] = $stringQuoteChar . $role->getRole() . $stringQuoteChar;
}
}
}
$uR = array_unique($uR);
$inString = implode(' OR s.identifier = ', $uR);

if (\is_object($user)) {
$inString .= ' OR s.identifier = "' . str_replace(
'\\',
'\\\\',
\get_class($user)
) . '-' . $user->getUserName() . '"';
$inString .= ' OR s.identifier = ' . $stringQuoteChar . get_class($user) . '-' . $user->getUserName() . $stringQuoteChar;
}

$objectIdentifierColumn = 'o.object_identifier';
if ($aclConnection->getDatabasePlatform()->getName() === 'postgresql') {
$objectIdentifierColumn = 'o.object_identifier::BIGINT';
}

$selectQuery = <<<SELECTQUERY
SELECT DISTINCT o.object_identifier as id FROM {$databasePrefix}acl_object_identities as o
INNER JOIN {$databasePrefix}acl_classes c ON c.id = o.class_id
LEFT JOIN {$databasePrefix}acl_entries e ON (
SELECT DISTINCT {$objectIdentifierColumn} as id FROM acl_object_identities as o
INNER JOIN acl_classes c ON c.id = o.class_id
LEFT JOIN acl_entries e ON (
e.class_id = o.class_id AND (e.object_identity_id = o.id
OR {$aclConnection->getDatabasePlatform()->getIsNullExpression('e.object_identity_id')})
)
LEFT JOIN {$databasePrefix}acl_security_identities s ON (
LEFT JOIN acl_security_identities s ON (
s.id = e.security_identity_id
)
WHERE c.class_type = {$rootEntity}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Expand Down
29 changes: 15 additions & 14 deletions src/Kunstmaan/AdminBundle/Helper/Security/Acl/AclNativeHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -67,14 +67,14 @@ public function apply(QueryBuilder $queryBuilder, PermissionDefinition $permissi
}

$aclConnection = $this->em->getConnection();
$stringQuoteChar = $aclConnection->getDatabasePlatform()->getStringLiteralQuoteCharacter();

$databasePrefix = is_file($aclConnection->getDatabase()) ? '' : $aclConnection->getDatabase().'.';
$rootEntity = $permissionDef->getEntity();
$linkAlias = $permissionDef->getAlias();
// Only tables with a single ID PK are currently supported
$linkField = $this->em->getClassMetadata($rootEntity)->getSingleIdentifierColumnName();

$rootEntity = '"' . str_replace('\\', '\\\\', $rootEntity) . '"';
$rootEntity = $stringQuoteChar . $rootEntity . $stringQuoteChar;
$query = $queryBuilder;

$builder = new MaskBuilder();
Expand All @@ -99,40 +99,41 @@ public function apply(QueryBuilder $queryBuilder, PermissionDefinition $permissi
}

// Security context does not provide anonymous role automatically.
$uR = array('"IS_AUTHENTICATED_ANONYMOUSLY"');
$uR = array($stringQuoteChar . 'IS_AUTHENTICATED_ANONYMOUSLY' . $stringQuoteChar);

foreach ($userRoles as $role) {
// The reason we ignore this is because by default FOSUserBundle adds ROLE_USER for every user
if (is_string($role)) {
if ($role !== 'ROLE_USER') {
$uR[] = '"' . $role . '"';
$uR[] = $stringQuoteChar . $role . $stringQuoteChar;
}
} else {
// Symfony 3.4 compatibility
if ($role->getRole() !== 'ROLE_USER') {
$uR[] = '"' . $role->getRole() . '"';
$uR[] = $stringQuoteChar . $role->getRole() . $stringQuoteChar;
}
}
}
$uR = array_unique($uR);
$inString = implode(' OR s.identifier = ', $uR);

if (\is_object($user)) {
$inString .= ' OR s.identifier = "' . str_replace(
'\\',
'\\\\',
\get_class($user)
) . '-' . $user->getUserName() . '"';
$inString .= ' OR s.identifier = ' . $stringQuoteChar . \get_class($user) . '-' . $user->getUserName() . $stringQuoteChar;
}

$objectIdentifierColumn = 'o.object_identifier';
if ($aclConnection->getDatabasePlatform()->getName() === 'postgresql') {
$objectIdentifierColumn = 'o.object_identifier::BIGINT';
}

$joinTableQuery = <<<SELECTQUERY
SELECT DISTINCT o.object_identifier as id FROM {$databasePrefix}acl_object_identities as o
INNER JOIN {$databasePrefix}acl_classes c ON c.id = o.class_id
LEFT JOIN {$databasePrefix}acl_entries e ON (
SELECT DISTINCT {$objectIdentifierColumn} as id FROM acl_object_identities as o
INNER JOIN acl_classes c ON c.id = o.class_id
LEFT JOIN acl_entries e ON (
e.class_id = o.class_id AND (e.object_identity_id = o.id
OR {$aclConnection->getDatabasePlatform()->getIsNullExpression('e.object_identity_id')})
)
LEFT JOIN {$databasePrefix}acl_security_identities s ON (
LEFT JOIN acl_security_identities s ON (
s.id = e.security_identity_id
)
WHERE c.class_type = {$rootEntity}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same question as comment above

Expand Down
11 changes: 10 additions & 1 deletion src/Kunstmaan/AdminBundle/Helper/Security/Acl/AclWalker.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,18 @@ public function walkFromClause($fromClause)
$tableAlias = $this->getSQLTableAlias($name, $alias);
$extraQuery = $this->getQuery()->getHint('acl.extra.query');

$tempAclView = <<<tempAclView
switch ($this->getConnection()->getDatabasePlatform()->getName()) {
case 'postgresql':
$tempAclView = <<<tempAclView
JOIN ({$extraQuery}) ta_ ON {$tableAlias}.id = ta_.id::integer
tempAclView;
break;
default:
$tempAclView = <<<tempAclView
JOIN ({$extraQuery}) ta_ ON {$tableAlias}.id = ta_.id
tempAclView;
break;
}

return $sql . ' ' . $tempAclView;
}
Expand Down
9 changes: 6 additions & 3 deletions src/Kunstmaan/AdminBundle/Repository/ExceptionRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,10 @@ public function markAllAsResolved()
{
return $this->createQueryBuilder('e')
->update()
->set('e.isResolved', 1)
->where('e.isResolved = 0')
->set('e.isResolved', ':resolved')
->where('e.isResolved = :unresolved')
->setParameter('resolved', true)
->setParameter('unresolved', false)
->getQuery()
->getSingleScalarResult();
}
Expand All @@ -36,7 +38,8 @@ public function findExceptionStatistics()
{
return $this->createQueryBuilder('e')
->select('COUNT(e.id) as cp_all, SUM(e.events) as cp_sum')
->where('e.isResolved = 0')
->where('e.isResolved = :isResolved')
->setParameter('isResolved', false)
->getQuery()
->getOneOrNullResult();
}
Expand Down
3 changes: 2 additions & 1 deletion src/Kunstmaan/AdminBundle/Repository/UserRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,9 @@ public function getUsersByRole($role)
->from('KunstmaanAdminBundle:User', 'u')
->innerJoin('u.groups', 'g')
->innerJoin('g.roles', 'r')
->where('u.enabled=1')
->where('u.enabled=:enabled')
->andWhere('r.role IN (:roles)')
->setParameter('enabled', true)
->setParameter('roles', $roles);

return $qb->getQuery()->getResult();
Expand Down
3 changes: 2 additions & 1 deletion src/Kunstmaan/AdminBundle/Resources/doc/Permissions.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,8 @@ public function findAllWithPermission(AclHelper $aclHelper, PermissionDefinition
{
$qb = $this->createQueryBuilder('b')
->select('b')
->where('b.deleted = 0');
->where('b.deleted = :deleted')
->setParameter('deleted', false);
$query = $aclHelper->apply($qb, $permissionDef);

return $query->getResult();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,10 @@ protected function setUp(): void
->will($this->returnValue('myDatabase'));

/* @var $platform AbstractPlatform */
$platform = $this->getMockForAbstractClass('Doctrine\DBAL\Platforms\AbstractPlatform');
$platform = $this->createMock(AbstractPlatform::class);
$platform->expects($this->any())
->method('getStringLiteralQuoteCharacter')
->willReturn($this->returnValue('#'));

$conn->expects($this->any())
->method('getDatabasePlatform')
Expand Down Expand Up @@ -202,9 +205,9 @@ public function testApply()
$this->assertEquals('n', $query->getHint('acl.entityRootTableDqlAlias'));

$aclQuery = $query->getHint('acl.extra.query');
$this->assertStringContainsString('"ROLE_SUBJECT"', $aclQuery);
$this->assertStringContainsString('"ROLE_KING"', $aclQuery);
$this->assertStringContainsString('"IS_AUTHENTICATED_ANONYMOUSLY"', $aclQuery);
$this->assertStringContainsString('#ROLE_SUBJECT#', $aclQuery);
$this->assertStringContainsString('#ROLE_KING#', $aclQuery);
$this->assertStringContainsString('#IS_AUTHENTICATED_ANONYMOUSLY#', $aclQuery);
$this->assertStringContainsString('MyUser', $aclQuery);
}

Expand Down Expand Up @@ -255,7 +258,7 @@ public function testApplyAnonymous()
$this->assertEquals('n', $query->getHint('acl.entityRootTableDqlAlias'));

$aclQuery = $query->getHint('acl.extra.query');
$this->assertStringContainsString('"IS_AUTHENTICATED_ANONYMOUSLY"', $aclQuery);
$this->assertStringContainsString('#IS_AUTHENTICATED_ANONYMOUSLY#', $aclQuery);
}

public function testGetAllowedEntityIds()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,10 @@ protected function setUp(): void
->will($this->returnValue('myDatabase'));

/* @var $platform AbstractPlatform */
$platform = $this->getMockForAbstractClass('Doctrine\DBAL\Platforms\AbstractPlatform');
$platform = $this->createMock(AbstractPlatform::class);
$platform->expects($this->any())
->method('getStringLiteralQuoteCharacter')
->willReturn($this->returnValue('#'));

$this->conn->expects($this->any())
->method('getDatabasePlatform')
Expand Down Expand Up @@ -151,9 +154,9 @@ public function testApply()
$qb = $this->object->apply($queryBuilder, $permissionDef);
$query = $qb->getSQL();

$this->assertStringContainsString('"ROLE_SUBJECT"', $query);
$this->assertStringContainsString('"ROLE_KING"', $query);
$this->assertStringContainsString('"IS_AUTHENTICATED_ANONYMOUSLY"', $query);
$this->assertStringContainsString('#ROLE_SUBJECT#', $query);
$this->assertStringContainsString('#ROLE_KING#', $query);
$this->assertStringContainsString('#IS_AUTHENTICATED_ANONYMOUSLY#', $query);
$this->assertStringContainsString('MyUser', $query);
}

Expand Down Expand Up @@ -191,7 +194,7 @@ public function testApplyAnonymous()
$qb = $this->object->apply($queryBuilder, $permissionDef);
$query = $qb->getSQL();

$this->assertStringContainsString('"IS_AUTHENTICATED_ANONYMOUSLY"', $query);
$this->assertStringContainsString('#IS_AUTHENTICATED_ANONYMOUSLY#', $query);
}

public function testGetTokenStorage()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public function testWalker()
$platform->expects($this->once())->method('appendLockHint')->willReturn($from);

$conn = $this->createMock(Connection::class);
$conn->expects($this->once())->method('getDatabasePlatform')->willReturn($platform);
$conn->expects($this->any())->method('getDatabasePlatform')->willReturn($platform);

$em = $this->createMock(EntityManager::class);
$query = $this->createMock(AbstractQuery::class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,8 @@ public function adaptQueryBuilder(QueryBuilder $queryBuilder, array $params = []
->select('b.id, b.node_id')
->from('kuma_node_translations', 'b')
->innerJoin('b', 'kuma_nodes', 'n', 'b.node_id = n.id')
->where('n.deleted = 0')
->where('n.deleted = :deleted')
->setParameter('deleted', false)
->andWhere('n.ref_entity_name = :class')
->setParameter('class', $this->getPageClass())
->addOrderBy('b.updated', 'DESC');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,6 @@ public function getNbResults()
$distinctString = 'DISTINCT ';
}
$statement = $query->select('COUNT('. $distinctString . $this->countField.') AS total_results')
->orderBy($this->countField)
->setMaxResults(1)
->execute();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ public function testNbResults()
$qb = $this->createMock(QueryBuilder::class);
$qb->expects($this->once())->method('getType')->willReturn(QueryBuilder::SELECT);
$qb->expects($this->once())->method('select')->willReturn($qb);
$qb->expects($this->once())->method('orderBy')->willReturn($qb);
$qb->expects($this->never())->method('orderBy');
$qb->expects($this->once())->method('setMaxResults')->with(1)->willReturn($qb);
$qb->expects($this->once())->method('execute')->willReturn($statement);

Expand All @@ -76,7 +76,7 @@ public function testNbResultsWithZeroResults()
$qb = $this->createMock(QueryBuilder::class);
$qb->expects($this->once())->method('getType')->willReturn(QueryBuilder::SELECT);
$qb->expects($this->once())->method('select')->willReturn($qb);
$qb->expects($this->once())->method('orderBy')->willReturn($qb);
$qb->expects($this->never())->method('orderBy');
$qb->expects($this->once())->method('setMaxResults')->with(1)->willReturn($qb);
$qb->expects($this->once())->method('execute')->willReturn($statement);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,8 @@ public function adaptQueryBuilder(QueryBuilder $queryBuilder)
$queryBuilder->innerJoin('b.node', 'n', 'WITH', 'b.node = n.id');
$queryBuilder->innerJoin('b.nodeVersions', 'nv', 'WITH', 'b.publicNodeVersion = nv.id');
$queryBuilder->andWhere('b.lang = :lang');
$queryBuilder->andWhere('n.deleted = 0');
$queryBuilder->andWhere('n.deleted = :deleted');
$queryBuilder->setParameter('deleted', false);
$queryBuilder->andWhere('n.refEntityName = :class');
$queryBuilder->addOrderBy('b.updated', 'DESC');
$queryBuilder->setParameter('lang', $this->locale);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ public function findActiveOverviewPages()
->innerJoin('KunstmaanNodeBundle:NodeVersion', 'v', 'WITH', 'a.id = v.refId')
->innerJoin('KunstmaanNodeBundle:NodeTranslation', 't', 'WITH', 't.publicNodeVersion = v.id')
->innerJoin('KunstmaanNodeBundle:Node', 'n', 'WITH', 't.node = n.id')
->where('n.deleted = 0')
->where('n.deleted = :deleted')
->setParameter('deleted', false)
->andWhere('v.refEntityName = :refname')
->setParameter('refname', $this->getEntityName());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public function testFindActiveOverviewPages()
$qb->expects($this->once())->method('from')->willReturn($qb);
$qb->expects($this->once())->method('where')->willReturn($qb);
$qb->expects($this->once())->method('andWhere')->willReturn($qb);
$qb->expects($this->once())->method('setParameter')->willReturn($qb);
$qb->expects($this->exactly(2))->method('setParameter')->willReturn($qb);
$qb->expects($this->once())->method('getQuery')->willReturn($query);

$em = $this->createMock(EntityManager::class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,10 @@ class {{ entity_class }}PageRepository extends AbstractArticlePageRepository
->innerJoin('KunstmaanNodeBundle:NodeVersion', 'v', 'WITH', 'a.id = v.refId')
->innerJoin('KunstmaanNodeBundle:NodeTranslation', 't', 'WITH', 't.publicNodeVersion = v.id')
->innerJoin('KunstmaanNodeBundle:Node', 'n', 'WITH', 't.node = n.id')
->where('t.online = 1')
->andWhere('n.deleted = 0')
->where('t.online = :online')
->setParameter('online', true)
->andWhere('n.deleted = :deleted')
->setParameter('deleted', false)
->andWhere('v.refEntityName = :refname')
->orderBy('a.date', 'DESC')
->setParameter('refname', "{{ namespace | replace({'\\': '\\\\'}) }}\\Entity\\Pages\\{{ entity_class }}Page");
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

//// is only required in LIKE clause and should not work with "="

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,8 @@ public function adaptQueryBuilder(QueryBuilder $queryBuilder)
{
$queryBuilder->andWhere('b.folder = :folder')
->setParameter('folder', $this->folder->getId())
->andWhere('b.deleted = 0')
->andWhere('b.deleted = :deleted')
->setParameter('deleted', false)
->orderBy('b.updatedAt', 'DESC');

if ($this->request->get('_route') == 'KunstmaanMediaBundle_chooser_show_folder') {
Expand Down
6 changes: 4 additions & 2 deletions src/Kunstmaan/MenuBundle/Form/MenuItemAdminType.php
Original file line number Diff line number Diff line change
Expand Up @@ -91,10 +91,12 @@ public function buildForm(FormBuilderInterface $builder, array $options)
$qb = $er->createQueryBuilder('nt')
->innerJoin('nt.publicNodeVersion', 'nv')
->innerJoin('nt.node', 'n')
->where('n.deleted = 0')
->where('n.deleted = :deleted')
->setParameter('deleted', false)
->andWhere('nt.lang = :lang')
->setParameter('lang', $locale)
->andWhere('nt.online = 1')
->andWhere('nt.online = :online')
->setParameter('online', true)
->orderBy('nt.title', 'ASC');
if ($rootNode) {
$qb->andWhere('n.lft >= :left')
Expand Down
3 changes: 2 additions & 1 deletion src/Kunstmaan/MenuBundle/Repository/MenuItemRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ public function getMenuItemsForLanguage($menuName, $locale)
->setParameter('locale', $locale)
->andWhere('m.name = :name')
->setParameter('name', $menuName)
->andWhere('nt.online = 1 OR mi.type = :url_type')
->andWhere('nt.online = :online OR mi.type = :url_type')
->setParameter('online', true)
->setParameter('url_type', BaseMenuItem::TYPE_URL_LINK);

$query = $query->getQuery();
Expand Down
Loading