Override an Override Service with Compiler Pass

I wanted to increase the length of name for MySQL table from 30 to 64 as I encountered this error:

[kiat@reporting misoro]$ sudo -u nginx php bin/console oro:migration:load --force
Process migrations...
Oro\Bundle\EntityExtendBundle\Migration\LoadEntityConfigStateMigration
Stars\Bundle\LoggerEventBundle\Migraions\Schema\v1_0\StarsLoggerEventBundle
    ERROR: Max table name length is 30. Please correct "sc_stars_logger_event_action_data" table 
in "Stars\Bundle\LoggerEventBundle\Migraions\Schema\v1_0\StarsLoggerEventBundle" migration

The code that returns length 30 is from:

namespace Oro\Bundle\MigrationBundle\Tools;

class DbIdentifierNameGenerator
{
    /**
     * Gets the max size of an identifier
     *
     * @return int
     */
    public function getMaxIdentifierSize()
    {
        return 30;
    }

I could override the parameters as it is defined in the services.yml:

parameters:
    oro_migration.db_id_name_generator.class: Stars\Bundle\MigrationBundle\Tools\DbIdentifierNameGenerator

However, that didn't work because of this:

[kiat@reporting misoro]$ sudo -unginx php bin/console debug:container --parameters | grep DbIdentifier
  oro_migration.db_id_name_generator.class 
Oro\Bundle\EntityExtendBundle\Tools\ExtendDbIdentifierNameGenerator 

I traced the above overriding to this code:

namespace Oro\Bundle\EntityExtendBundle\DependencyInjection\Compiler;

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

class MigrationConfigPass implements CompilerPassInterface
{
    // ...
    const MIGRATIONS_NAME_GENERATOR_CLASS_PARAM = 'oro_migration.db_id_name_generator.class';

    /**
     * {@inheritdoc}
     */
    public function process(ContainerBuilder $container)
    {
        if ($container->hasParameter(self::MIGRATIONS_NAME_GENERATOR_CLASS_PARAM)) {
            $container->setParameter(
                self::MIGRATIONS_NAME_GENERATOR_CLASS_PARAM,
                'Oro\Bundle\EntityExtendBundle\Tools\ExtendDbIdentifierNameGenerator'
            );
        }
        // ...
    }
}

So, I needed to override an override service. There are a few ways to override a service, but in this case, only using compiler pass Show archive.org snapshot worked for me.

Create a Mirror Bundle

src\Stars\Bundle\EntityExtendBundle\StarsEntityExtendBundle.php

<?php

namespace Stars\Bundle\EntityExtendBundle;

use Stars\Bundle\EntityExtendBundle\DependencyInjection\Compiler\MigrationConfigPass;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\Bundle\Bundle;

class StarsEntityExtendBundle extends Bundle
{
    public function build(ContainerBuilder $container)
    {
        parent::build($container);

        $container->addCompilerPass(new MigrationConfigPass());
    }

}

src\Stars\Bundle\EntityExtendBundle\Resources\config\oro\bundles.yml

bundles:
    - Stars\Bundle\EntityExtendBundle\StarsEntityExtendBundle

Create a Compiler Pass

src\Stars\Bundle\EntityExtendBundle\DependencyInjection\Compiler\MigrationConfigPass.php

<?php

namespace Stars\Bundle\EntityExtendBundle\DependencyInjection\Compiler;

use Oro\Bundle\EntityExtendBundle\DependencyInjection\Compiler\MigrationConfigPass as OroMigrationConfigPass;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;

class MigrationConfigPass implements CompilerPassInterface
{
    /**
     * {@inheritdoc}
     */
    public function process(ContainerBuilder $container)
    {
        if ($container->hasParameter(OroMigrationConfigPass::MIGRATIONS_NAME_GENERATOR_CLASS_PARAM)) {
            $container->setParameter(
                OroMigrationConfigPass::MIGRATIONS_NAME_GENERATOR_CLASS_PARAM,
                'Stars\Bundle\EntityExtendBundle\Tools\ExtendDbIdentifierNameGenerator'
            );
        }
    }
}

Create the Override Class Mirroring the Overridden Class

src\Stars\Bundle\EntityExtendBundle\Tools\ExtendDbIdentifierNameGenerator.php

<?php

namespace Stars\Bundle\EntityExtendBundle\Tools;

// use Oro\Bundle\MigrationBundle\Tools\DbIdentifierNameGenerator as OroDbIdentifierNameGenerator;
use Oro\Bundle\EntityExtendBundle\Tools\ExtendDbIdentifierNameGenerator as OroExtendDbIdentifierNameGenerator;

class ExtendDbIdentifierNameGenerator extends OroExtendDbIdentifierNameGenerator
{
    /**
     * Override
     * Gets the max length of name for table and column.
     * Max length of table and column name in MySQL is 64
     *
     * @return int
     */
    public function getMaxIdentifierSize()
    {
        return 64; // OroDbIdentifierNameGenerator returns 30.
    }
}

Test the Overriding

[kiat@reporting misoro]$  sudo -unginx php bin/console debug:container --parameters | grep DbIdentifier                                                                                                                     
  oro_migration.db_id_name_generator.class
Stars\Bundle\EntityExtendBundle\Tools\ExtendDbIdentifierNameGenerator     

 // To search for a specific parameter, re-run this command with a search term.
 // (e.g. debug:container --parameter=kernel.debug)

Success !

kiatng About 5 years ago