merged branch vicb/acl (PR #3560)
Commits -------6d27aec
[SecurityBundle] Improve the init:acl commande809458
[Security]replaced acl:init command with postGenerateSchema listener Discussion ---------- [WIP][Security]replaced acl:init command with postGenerateSchema listener Attempt to fix #2091. The code is from @schmittjoh (see #1313) but was never merged. The difference is that the `init:acl` command has not been dropped in order to overcome [the limitations](https://github.com/symfony/symfony/pull/1313#issuecomment-1387091) described by @stof. @stof do you think this is ok ? Left to fix: * Using the code from this PR, the generated migration does not drop the tables but still alter them, @stof you know this part of the code far better than me. I would appreacite your feedback on this PR and any hint on solving the remaining item. Thanks.
This commit is contained in:
commit
fb7b88b226
@ -15,6 +15,7 @@ use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
|
||||
use Symfony\Component\Security\Acl\Dbal\Schema;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Doctrine\DBAL\Schema\SchemaException;
|
||||
|
||||
/**
|
||||
* Installs the tables required by the ACL system
|
||||
@ -50,26 +51,19 @@ EOT
|
||||
*/
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$connection = $this->getContainer()->get('security.acl.dbal.connection');
|
||||
$sm = $connection->getSchemaManager();
|
||||
$tableNames = $sm->listTableNames();
|
||||
$tables = array(
|
||||
'class_table_name' => $this->getContainer()->getParameter('security.acl.dbal.class_table_name'),
|
||||
'sid_table_name' => $this->getContainer()->getParameter('security.acl.dbal.sid_table_name'),
|
||||
'oid_table_name' => $this->getContainer()->getParameter('security.acl.dbal.oid_table_name'),
|
||||
'oid_ancestors_table_name' => $this->getContainer()->getParameter('security.acl.dbal.oid_ancestors_table_name'),
|
||||
'entry_table_name' => $this->getContainer()->getParameter('security.acl.dbal.entry_table_name'),
|
||||
);
|
||||
$container = $this->getContainer();
|
||||
|
||||
foreach ($tables as $table) {
|
||||
if (in_array($table, $tableNames, true)) {
|
||||
$output->writeln(sprintf('The table "%s" already exists. Aborting.', $table));
|
||||
$connection = $container->get('security.acl.dbal.connection');
|
||||
$schema = $container->get('security.acl.dbal.schema');
|
||||
|
||||
return;
|
||||
}
|
||||
try {
|
||||
$schema->addToSchema($connection->getSchemaManager()->createSchema());
|
||||
} catch (SchemaException $e) {
|
||||
$output->writeln("Aborting: " . $e->getMessage());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$schema = new Schema($tables, $sm->createSchemaConfig());
|
||||
foreach ($schema->toSql($connection->getDatabasePlatform()) as $sql) {
|
||||
$connection->exec($sql);
|
||||
}
|
||||
|
@ -89,7 +89,11 @@ class MainConfiguration implements ConfigurationInterface
|
||||
->children()
|
||||
->arrayNode('acl')
|
||||
->children()
|
||||
->scalarNode('connection')->setInfo('any name configured in doctrine.dbal section')->end()
|
||||
->scalarNode('connection')
|
||||
->defaultValue('default')
|
||||
->cannotBeEmpty()
|
||||
->setInfo('any name configured in doctrine.dbal section')
|
||||
->end()
|
||||
->arrayNode('cache')
|
||||
->addDefaultsIfNotSet()
|
||||
->children()
|
||||
|
@ -133,9 +133,16 @@ class SecurityExtension extends Extension
|
||||
{
|
||||
$loader->load('security_acl_dbal.xml');
|
||||
|
||||
if (isset($config['connection'])) {
|
||||
$container->setAlias('security.acl.dbal.connection', sprintf('doctrine.dbal.%s_connection', $config['connection']));
|
||||
}
|
||||
$container->setAlias('security.acl.dbal.connection', sprintf('doctrine.dbal.%s_connection', $config['connection']));
|
||||
|
||||
$container
|
||||
->getDefinition('security.acl.dbal.schema_listener')
|
||||
->addTag('doctrine.event_listener', array(
|
||||
'connection' => $config['connection'],
|
||||
'event' => 'postGenerateSchema'
|
||||
))
|
||||
;
|
||||
|
||||
$container->getDefinition('security.acl.cache.doctrine')->addArgument($config['cache']['prefix']);
|
||||
|
||||
$container->setParameter('security.acl.dbal.class_table_name', $config['tables']['class']);
|
||||
|
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony framework.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
namespace Symfony\Bundle\SecurityBundle\EventListener;
|
||||
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Doctrine\ORM\Tools\Event\GenerateSchemaEventArgs;
|
||||
|
||||
/**
|
||||
* Merges ACL schema into the given schema.
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*/
|
||||
class AclSchemaListener
|
||||
{
|
||||
private $container;
|
||||
|
||||
public function __construct(ContainerInterface $container)
|
||||
{
|
||||
$this->container = $container;
|
||||
}
|
||||
|
||||
public function postGenerateSchema(GenerateSchemaEventArgs $args)
|
||||
{
|
||||
$schema = $args->getSchema();
|
||||
$this->container->get('security.acl.dbal.schema')->addToSchema($schema);
|
||||
}
|
||||
}
|
@ -6,6 +6,8 @@
|
||||
|
||||
<parameters>
|
||||
<parameter key="security.acl.dbal.provider.class">Symfony\Component\Security\Acl\Dbal\MutableAclProvider</parameter>
|
||||
<parameter key="security.acl.dbal.schema.class">Symfony\Component\Security\Acl\Dbal\Schema</parameter>
|
||||
<parameter key="security.acl.dbal.schema_listener.class">Symfony\Bundle\SecurityBundle\EventListener\AclSchemaListener</parameter>
|
||||
</parameters>
|
||||
|
||||
<services>
|
||||
@ -24,6 +26,20 @@
|
||||
<argument type="service" id="security.acl.cache" on-invalid="null" />
|
||||
</service>
|
||||
|
||||
<service id="security.acl.dbal.schema" class="%security.acl.dbal.schema.class%">
|
||||
<argument type="collection">
|
||||
<argument key="class_table_name">%security.acl.dbal.class_table_name%</argument>
|
||||
<argument key="entry_table_name">%security.acl.dbal.entry_table_name%</argument>
|
||||
<argument key="oid_table_name">%security.acl.dbal.oid_table_name%</argument>
|
||||
<argument key="oid_ancestors_table_name">%security.acl.dbal.oid_ancestors_table_name%</argument>
|
||||
<argument key="sid_table_name">%security.acl.dbal.sid_table_name%</argument>
|
||||
</argument>
|
||||
<argument type="service" id="security.acl.dbal.connection" />
|
||||
</service>
|
||||
<service id="security.acl.dbal.schema_listener" class="%security.acl.dbal.schema_listener.class%" public="false">
|
||||
<argument type="service" id="service_container" />
|
||||
</service>
|
||||
|
||||
<service id="security.acl.provider" alias="security.acl.dbal.provider" />
|
||||
|
||||
<service id="security.acl.cache.doctrine" class="%security.acl.cache.doctrine.class%" public="false">
|
||||
|
@ -13,6 +13,7 @@ namespace Symfony\Component\Security\Acl\Dbal;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema as BaseSchema;
|
||||
use Doctrine\DBAL\Schema\SchemaConfig;
|
||||
use Doctrine\DBAL\Connection;
|
||||
|
||||
/**
|
||||
* The schema used for the ACL system.
|
||||
@ -26,11 +27,13 @@ final class Schema extends BaseSchema
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param array $options the names for tables
|
||||
* @param SchemaConfig $schemaConfig
|
||||
* @param array $options the names for tables
|
||||
* @param Connection $connection
|
||||
*/
|
||||
public function __construct(array $options, SchemaConfig $schemaConfig = null)
|
||||
public function __construct(array $options, Connection $connection = null)
|
||||
{
|
||||
$schemaConfig = null === $connection ? null : $connection->getSchemaManager()->createSchemaConfig();
|
||||
|
||||
parent::__construct(array(), array(), $schemaConfig);
|
||||
|
||||
$this->options = $options;
|
||||
@ -42,6 +45,22 @@ final class Schema extends BaseSchema
|
||||
$this->addEntryTable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Merges ACL schema with the given schema.
|
||||
*
|
||||
* @param BaseSchema $schema
|
||||
*/
|
||||
public function addToSchema(BaseSchema $schema)
|
||||
{
|
||||
foreach ($this->getTables() as $table) {
|
||||
$schema->_addTable($table);
|
||||
}
|
||||
|
||||
foreach ($this->getSequences() as $sequence) {
|
||||
$schema->_addSequence($sequence);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the class table to the schema
|
||||
*/
|
||||
|
Reference in New Issue
Block a user