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

dbal connection hardcoded to default #140

Closed
ghost opened this issue Jul 8, 2015 · 5 comments · Fixed by #355
Closed

dbal connection hardcoded to default #140

ghost opened this issue Jul 8, 2015 · 5 comments · Fixed by #355
Labels

Comments

@ghost
Copy link

ghost commented Jul 8, 2015

I have a problem with database conections. I have a sqlite database for development and a sqlserver database for other enviroments.

I have this config file

config.yml

doctrine:
    dbal:
        default_connection:     "%database_default_connection%"
        connections:
            default:
                driver:         "%database_driver%"
                path:           "%database_path%"
            sqlserver:
                driver_class:   "%database_class%"
                host:           "%database_host%"
                port:           "%database_port%"
                dbname:         "%database_name%"
                user:           "%database_user%"
                password:       "%database_password%"
                charset:        UTF8

parameters.yml.dev

parameters:
    database_default_connection : default

parameters.yml.prod

parameters:
    database_default_connection : sqlserver

In production enviroment the audit bundle does`t work. I think this is due to de bundle always use de hardcode "default" connection.

In fact, if i rename the "default" connection name to "sqlite" and change

parameters:
    database_default_connection : sqlite

It have this error during "composer install"

he Doctrine connection "default" referenced in service "simplethings_entityaudit.log_revisions_l│
istener" does not exist. Available connections names: sqlite, sqlserve

I see the service and in fact, it have hardcode the connection default

<service id="simplethings_entityaudit.log_revisions_listener" class="SimpleThings\EntityAudit\EventListener\LogRevisionsListener">
            <argument id="simplethings_entityaudit.manager" type="service" />
            <tag name="doctrine.event_subscriber" connection="default" />
        </service>

Any suggestion?

@vbartusevicius
Copy link

Same problem here.
I think best solution would be to remove connection="default" as this way doctrine will use the default connection from config automatically.

@vbartusevicius
Copy link

As working workaround I could suggest to create a compiler pass like this:

class OverrideEntityAuditBundleConnectionCompilerPass implements CompilerPassInterface
{
    private $servicesToOverride = array(
        'simplethings_entityaudit.log_revisions_listener',
        'simplethings_entityaudit.create_schema_listener',
    );

    public function process(ContainerBuilder $container)
    {
        foreach ($this->servicesToOverride as $adminId) {
            if (!$container->hasDefinition($adminId)) {
                continue;
            }

            $definition = $container->getDefinition($adminId);
            if ($definition->hasTag('doctrine.event_subscriber')) {
                $tags = $definition->getTag('doctrine.event_subscriber');

                $connectionTags = $tags[0];
                if (isset($connectionTags['connection'])) {
                    unset ($connectionTags['connection']);
                }

                $definition->clearTag('doctrine.event_subscriber');
                $definition->addTag('doctrine.event_subscriber', $connectionTags);
            }
        }
    }
}

Be sure to move DoctrineBundle AFTER the bunde this compiler pass exists in Your AppKernel.

@ju1ius
Copy link

ju1ius commented Feb 1, 2016

Hi,
building on @vbartusevicius suggestion, this is what I had to do to make it work:

namespace AppBundle\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;

/**
 * Override harcoded Doctrine configuration in SimpleThingsEntityAuditBundle.
 * 
 * Be sure to add this pass in AppKernel::prepareContainer method,
 * BEFORE calling parent::prepareContainer().
 *
 * @see https://github.com/simplethings/EntityAudit/issues/140
 *
 */
class OverrideEntityAuditConfigurationCompilerPass implements CompilerPassInterface
{
    const CONNECTION_NAME = 'your_connection_name';
    const ENTITY_MANAGER_ID = 'doctrine.orm.your_entity_manager';

    public function process(ContainerBuilder $container)
    {
        $this->overrideEntityManager($container);
        $this->overrideDoctrineSubscribers($container);
    }

    private function overrideEntityManager(ContainerBuilder $container)
    {
        if ($container->hasDefinition('simplethings_entityaudit.reader')) {
            $definition = $container->getDefinition('simplethings_entityaudit.reader');
            $definition->replaceArgument(0, new Reference(self::ENTITY_MANAGER_ID));
        }
    }

    private function overrideDoctrineSubscribers(ContainerBuilder $container)
    {
        $servicesToOverride = [
            'simplethings_entityaudit.log_revisions_listener',
            'simplethings_entityaudit.create_schema_listener',
        ];
        foreach ($servicesToOverride as $serviceId) {
            if (!$container->hasDefinition($serviceId)) {
                continue;
            }

            $definition = $container->getDefinition($serviceId);
            if ($definition->hasTag('doctrine.event_subscriber')) {
                $tags = $definition->getTag('doctrine.event_subscriber');
                $connectionTags = $tags[0];
                if (isset($connectionTags['connection'])) {
                    unset($connectionTags['connection']);
                }
                $connectionTags['connection'] = self::CONNECTION_NAME;

                $definition->clearTag('doctrine.event_subscriber');
                $definition->addTag('doctrine.event_subscriber', $connectionTags);
            }
        }
    }
}

And then in app/AppKernel.php

use Symfony\Component\DependencyInjection\ContainerBuilder;
use AppBundle\DependencyInjection\Compiler\OverrideEntityAuditConfigurationCompilerPass;

class AppKernel extends Kernel
{
    // ...

    /**
     * Prepares the ContainerBuilder before it is compiled.
     *
     * @param ContainerBuilder $container A ContainerBuilder instance
     */
    protected function prepareContainer(ContainerBuilder $container)
    {
        $container->addCompilerPass(new OverrideEntityAuditConfigurationCompilerPass());
        parent::prepareContainer($container);
    }
}

@borderland-it
Copy link

@ju1ius did this solution also work for multiple connections?

@DavidBadura
Copy link
Contributor

should be solved by #257

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants