1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Tahoe\Bundle\MultiTenancyBundle\Manager; |
4
|
|
|
|
5
|
|
|
use Doctrine\ORM\EntityManager; |
6
|
|
|
use Psr\Log\LoggerInterface; |
7
|
|
|
use Symfony\Component\Form\FormInterface; |
8
|
|
|
use Tahoe\Bundle\MultiTenancyBundle\Entity\Tenant; |
9
|
|
|
use Tahoe\Bundle\MultiTenancyBundle\Factory\TenantFactory; |
10
|
|
|
use Tahoe\Bundle\MultiTenancyBundle\Gateway\GatewayManagerInterface; |
11
|
|
|
use Tahoe\Bundle\MultiTenancyBundle\Handler\TenantUserHandler; |
12
|
|
|
use Tahoe\Bundle\MultiTenancyBundle\Model\MultiTenantUserInterface; |
13
|
|
|
use Tahoe\Bundle\MultiTenancyBundle\Service\TenantAwareRouter; |
14
|
|
|
|
15
|
|
|
class RegistrationManager |
16
|
|
|
{ |
17
|
|
|
/** |
18
|
|
|
* @var EntityManager |
19
|
|
|
*/ |
20
|
|
|
protected $entityManager; |
21
|
|
|
|
22
|
|
|
/** |
23
|
|
|
* @var TenantFactory |
24
|
|
|
*/ |
25
|
|
|
protected $tenantFactory; |
26
|
|
|
|
27
|
|
|
/** |
28
|
|
|
* @var TenantUserHandler |
29
|
|
|
*/ |
30
|
|
|
protected $tenantUserHandler; |
31
|
|
|
|
32
|
|
|
/** @var GatewayManagerInterface */ |
33
|
|
|
protected $gatewayManager; |
34
|
|
|
/** |
35
|
|
|
* @var LoggerInterface |
36
|
|
|
*/ |
37
|
|
|
private $logger; |
38
|
|
|
|
39
|
|
|
/** |
40
|
|
|
* @param EntityManager $entityManager |
41
|
|
|
* @param TenantFactory $tenantFactory |
42
|
|
|
* @param TenantUserHandler $tenantUserHandler |
43
|
|
|
* @param LoggerInterface $logger |
44
|
|
|
* @param GatewayManagerInterface $gatewayManager |
45
|
|
|
*/ |
46
|
|
|
public function __construct(EntityManager $entityManager, TenantFactory $tenantFactory, |
|
|
|
|
47
|
|
|
TenantUserHandler $tenantUserHandler, LoggerInterface $logger, |
48
|
|
|
GatewayManagerInterface $gatewayManager = null) |
49
|
|
|
{ |
50
|
|
|
$this->entityManager = $entityManager; |
51
|
|
|
$this->tenantFactory = $tenantFactory; |
52
|
|
|
$this->tenantUserHandler = $tenantUserHandler; |
53
|
|
|
$this->gatewayManager = $gatewayManager; |
54
|
|
|
$this->logger = $logger; |
55
|
|
|
} |
56
|
|
|
|
57
|
|
|
/** |
58
|
|
|
* @param MultiTenantUserInterface $user |
59
|
|
|
* @param FormInterface $form |
|
|
|
|
60
|
|
|
* |
61
|
|
|
* @return Tenant |
62
|
|
|
* @throws \Exception |
63
|
|
|
*/ |
64
|
|
|
public function createTenant(MultiTenantUserInterface $user, $tenantName, $tenantSubdomain = '') |
65
|
|
|
{ |
66
|
|
|
$this->logger->info(sprintf('Creating new tenant with name %s and subdomain %s', |
67
|
|
|
$tenantName, $tenantSubdomain)); |
68
|
|
|
|
69
|
|
|
/** @var Tenant $tenant */ |
70
|
|
|
$tenant = $this->tenantFactory->createNew(); |
71
|
|
|
$tenant->setName($tenantName); |
72
|
|
|
$tenantSubdomain = $tenantSubdomain ?: $this->createSubdomainFromTenant($tenantName); |
73
|
|
|
$tenant->setSubdomain($tenantSubdomain); |
74
|
|
|
|
75
|
|
|
$this->entityManager->persist($tenant); |
76
|
|
|
// add as active tenant |
77
|
|
|
$user->setActiveTenant($tenant); |
78
|
|
|
$this->entityManager->flush(); |
79
|
|
|
|
80
|
|
|
$this->tenantUserHandler->addUserToTenant($user, $tenant, array('ROLE_ADMIN')); |
81
|
|
|
$this->entityManager->flush(); |
82
|
|
|
|
83
|
|
|
// we create a new account for gateway |
84
|
|
|
if (null !== $this->gatewayManager) { |
85
|
|
|
$this->logger->info(sprintf('Creating new account for tenant using gatewaymanager %s', |
86
|
|
|
get_class($this->gatewayManager))); |
87
|
|
|
$this->gatewayManager->createAccount($tenant); |
88
|
|
|
} else { |
89
|
|
|
$this->logger->info('No gatewaymanager configured'); |
90
|
|
|
} |
91
|
|
|
|
92
|
|
|
return $tenant; |
93
|
|
|
} |
94
|
|
|
|
95
|
|
|
/** |
96
|
|
|
* @param $tenantName |
97
|
|
|
* @return mixed|string |
98
|
|
|
*/ |
99
|
|
|
private function createSubdomainFromTenant($tenantName) |
100
|
|
|
{ |
101
|
|
|
// replace non letter or digits by - |
102
|
|
|
$subdomain = preg_replace('~[^\\pL\d]+~u', '-', $tenantName); |
103
|
|
|
|
104
|
|
|
// trim |
105
|
|
|
$subdomain = trim($subdomain, '-'); |
106
|
|
|
|
107
|
|
|
// transliterate |
108
|
|
|
$subdomain = iconv('utf-8', 'us-ascii//TRANSLIT', $subdomain); |
109
|
|
|
|
110
|
|
|
// lowercase |
111
|
|
|
$subdomain = strtolower($subdomain); |
112
|
|
|
|
113
|
|
|
// remove unwanted characters |
114
|
|
|
$subdomain = preg_replace('~[^-\w]+~', '', $subdomain); |
115
|
|
|
|
116
|
|
|
if (empty($subdomain)) |
117
|
|
|
{ |
118
|
|
|
return 'n-a'; |
119
|
|
|
} |
120
|
|
|
|
121
|
|
|
return $subdomain; |
122
|
|
|
} |
123
|
|
|
} |
124
|
|
|
|
The
EntityManager
might become unusable for example if a transaction is rolled back and it gets closed. Let’s assume that somewhere in your application, or in a third-party library, there is code such as the following:If that code throws an exception and the
EntityManager
is closed. Any other code which depends on the same instance of theEntityManager
during this request will fail.On the other hand, if you instead inject the
ManagerRegistry
, thegetManager()
method guarantees that you will always get a usable manager instance.