Как загрузить конфигурацию после входа в Symfony - PullRequest
1 голос
/ 09 октября 2019

У меня есть приложение Symfony 3.4, которое может содержать несколько компаний. У каждой компании есть свой собственный конфиг и свои данные в БД, поэтому мне нужно, чтобы у каждой компании был свой БД. Когда любой пользователь входит в систему, приложение имеет «основную базу данных», содержащую информацию о пользователе. После входа пользователя приложение должно изменить конфигурацию для подключения к базе данных компании пользователя, которая была сохранена в «основной базе данных».

Необходимо выполнить следующие шаги:

  • Один пользователь вводит своего пользователя ипароль
  • приложение просматривает центральную базу данных и получает аутентификацию пользователя.
  • Приложение получает конфигурацию пользователя для изменения.
  • Приложение меняет конфигурацию, и теперь запрос sql будетв дб.

Это возможно? Если нет, есть ли альтернатива?

Большое спасибо!

Ответы [ 2 ]

0 голосов
/ 10 октября 2019

Я нашел следующее решение для Symfony 4, и я думаю, что оно должно работать и для Symfony 3.4.

Я создал службу, которая копирует менеджер сущностей по умолчанию в новый, подключающийся к другой базе данных:

namespace App\Service;

use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
use Doctrine\ORM\EntityManagerInterface;

class CustomEntityManagerHelper 
{
    private $em;

    public function __construct(EntityManagerInterface $entityManager)
    {
        $this->em = $entityManager;
    }

    /*
     * get entity manager for another database
     */
    public function getManagerForDatabase($db_name): EntityManagerInterface
    {
        $conn = array(
            'driver' => 'pdo_mysql',
            'user' => 'root',
            'password' => 'mypass',
            'dbname' => $db_name
        );

        return \Doctrine\ORM\EntityManager::create(
            $conn,
            $this->em->getConfiguration(),
            $this->em->getEventManager()
        );
    }
}

До сих пор это было очень просто, но класс Repository все еще использует менеджер сущностей по умолчанию. Поэтому я добавил метод setEntityManager в репозитории:

<?php

namespace App\Repository;

use App\Entity\Product;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Common\Persistence\ManagerRegistry;

use Doctrine\ORM\EntityManagerInterface;

class ProductRepository extends ServiceEntityRepository
{
    public function __construct(ManagerRegistry $registry)
    {
        parent::__construct($registry, Product::class);
    }

    public function setEntityManager(EntityManagerInterface $entityManager): self
    {
        $this->_em = $entityManager;

        return $this;
    }

    // custom methods here
}

Теперь я могу использовать менеджер пользовательских сущностей И установить его в репозиторий:

use App\Service\CustomEntityManagerHelper;

// ...

/**
 * @Route("/products", name="app_product", methods={"GET"})
 */
public function index(CustomEntityManagerHelper $helper): Response
{
    $myManager = $helper->getManagerForDatabase($this->getUser()->getDatabaseName());

    $products = $myManager->getRepository('App:Product')
        ->setEntityManager($myManager)                  // IMPORTANT!
        ->findAll();

    return $this->render('product/index.html.twig', [
        'products' => $products
    ]);
}
0 голосов
/ 10 октября 2019

Вы должны работать здесь с несколькими менеджерами сущностей и соединениями , и идея состоит в том, чтобы использовать абонента, который извлекает текущего клиента на основе пользователя. Этот подписчик (или другой сервис) установит глобальную переменную, содержащую имя менеджера сущностей.

// A subscriber (high level priority) or a service already set $customerName

// In your controller or in a service
$customerEntityManager = $this->getDoctrine()->getManager($customerName);

Проверьте также этот пакет для идей https://github.com/vmeretail/multi-tenancy-bundle

Редактировать

Используйте и адаптируйте к своим файлам этот файл https://github.com/vmeretail/multi-tenancy-bundle/blob/master/Service/TenantResolver.php

Здесь вам просто нужно разрешить арендатора от текущего пользователя.

В вашем контроллере:

...

public function index(TenantResolver $tenantResolver)
{
    $customerEntityManager = $this->getDoctrine()->getManager($tenantResolver->getTenant()->getName()); // or getId() or something else
}

В сервисе:

...

use Doctrine\Common\Persistence\ManagerRegistry;

private $tenantResolver;
private $managerRegistry;

public function__construct(TenantResolver $tenantResolver, ManagerRegistry $managerRegistry)
{
    $this->tenantResolver = $tenantResolver;
    $this->managerRegistry = $managerRegistry;
}

public function doSomething()
{
    $this->managerRegistry->getManager($this->tenantResolver->getTenant()->getName());  // or getId() or something else
}

Идея в том, что здесь должно быть что-то лучше, например, непосредственное внедрение правильного менеджера в конструктор сервиса / контроллера.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...