0

I'm trying to create a dynamic connection to databases.

For that I have:


// App/Services/Config/Database/Connection.php

<?php

namespace App\Service\Config\Database;

use Doctrine\DBAL\Driver;
use Doctrine\DBAL\Configuration;
use Doctrine\Common\EventManager;

use Lexik\Bundle\JWTAuthenticationBundle\Services\JWTTokenManagerInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;

class Connection extends \Doctrine\DBAL\Connection
{
    public function __construct(
        array $params,
        Driver $driver,
        ?Configuration $config = null,
        ?EventManager $eventManager = null
    )
    {
        $company = "api";
        $db_name = "speyce_" . $company;
            $params['dbname'] = $db_name;
        parent::__construct($params, $driver, $config, $eventManager);
    }        
}

I got the DB name in the payload of JWT, like this:


// App/Service/ConnectionService.php

<?php

namespace App\Service;

use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Lexik\Bundle\JWTAuthenticationBundle\Services\JWTTokenManagerInterface;

class ConnectionService
{
    public function dbName(
        TokenStorageInterface $tokenStorageInterface,
        JWTTokenManagerInterface $jwtManager
    )
    {
        $decodedJwtToken = $jwtManager->decode($tokenStorageInterface->getToken());
        return $decodedJwtToken['company'];
    }
}

These 2 features work independently. But how can I call my service's method (connectionService->dbName) in Connection.php?

I can't call my ConnectionService in the parameters of the Constructor, because it only accepts 4 parameters.

Jason Aller
  • 3,541
  • 28
  • 38
  • 38
Mohamed 19
  • 7
  • 1
  • 9

1 Answers1

0

I think you can Inject it in the constructor like: // App/Services/Config/Database/Connection.php

<?php

namespace App\Service\Config\Database;

use Doctrine\DBAL\Driver;
use Doctrine\DBAL\Configuration;
use Doctrine\Common\EventManager;
use App\Service\ConnectionService;
use Lexik\Bundle\JWTAuthenticationBundle\Services\JWTTokenManagerInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;

class Connection extends \Doctrine\DBAL\Connection
{
    /**
     *@var ConnectionService
     */
    protected $connectionService;

    public function __construct(
        ConnectionService $connectionService
        array $params,
        Driver $driver,
        ?Configuration $config = null,
        ?EventManager $eventManager = null
    )
    {
        $company = "api";
        $db_name = "speyce_" . $company;
            $params['dbname'] = $db_name;
        parent::__construct($params, $driver, $config, $eventManager);
        $this->$connectionService = $connectionService;
    }        
}

Or using the setter injection :

namespace App\Service\Config\Database;

use Doctrine\DBAL\Driver;
use Doctrine\DBAL\Configuration;
use Doctrine\Common\EventManager;
use App\Service\ConnectionService;
use Lexik\Bundle\JWTAuthenticationBundle\Services\JWTTokenManagerInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;

class Connection extends \Doctrine\DBAL\Connection
{
    /**
     *@var ConnectionService
     */
    protected $connectionService;

    public function __construct(
        array $params,
        Driver $driver,
        ?Configuration $config = null,
        ?EventManager $eventManager = null
    )
    {
        $company = "api";
        $db_name = "speyce_" . $company;
            $params['dbname'] = $db_name;
        parent::__construct($params, $driver, $config, $eventManager);
    }   

    public function setConnectionService(ConnectionService $cs){
       $this->connectionService = $cs
    }     
}

In your services.yml

  connection.service:
      class: App\Service\ConnectionService

    App\Service\Config\Database\Connection:
      calls:
        - ['setConnectionService', ["@connection.service"]]
Yassine CHABLI
  • 3,459
  • 2
  • 23
  • 43
  • 1
    Assuming they are using the Symfony framework then your injection strategy is not going to work. The connection will not be pulled from the container. Furthermore, the goal is to pull the database name from a request parameter which will not be available when the connection is created. It is a challenging question without a good solution that I know of. – Cerad Oct 08 '19 at 17:21
  • Thank you for your help. The first solution don't work beause the Constructor doesn't accept more than 4 parameters. I instanciate the second solution, but I don't know how can I recover the content of my method connectionService->dbName() My goal is to put result of dbName() in my variable "company" (which is in my Constructor).. An Idea how I can use dbName() in the Constructor of Connection.php ? – Mohamed 19 Oct 08 '19 at 17:47