-
Notifications
You must be signed in to change notification settings - Fork 36
Expand file tree
/
Copy path13-shared-entities.php
More file actions
98 lines (78 loc) · 2.5 KB
/
13-shared-entities.php
File metadata and controls
98 lines (78 loc) · 2.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
<?php
/**
* Example 13: Shared Entities with #[TenantShared]
*
* Mark entities that should be shared across tenants (with optional exclusions).
* This is useful for reference data, feature flags, or shared catalogs.
*/
namespace App\Entity\Tenant;
use Doctrine\ORM\Mapping as ORM;
use Hakam\MultiTenancyBundle\Attribute\TenantShared;
/**
* This entity is shared across ALL tenants.
* Every tenant sees the same data.
*/
#[TenantShared]
#[ORM\Entity]
#[ORM\Table(name: 'shared_plan')]
class Plan
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column(type: 'integer')]
private ?int $id = null;
#[ORM\Column(type: 'string', length: 100)]
private string $name;
#[ORM\Column(type: 'decimal', precision: 10, scale: 2)]
private string $monthlyPrice;
// ...getters/setters
}
/**
* This entity is shared but with exclusions.
* Tenants "tenant_free" and "tenant_trial" don't get access.
*/
#[TenantShared(
excludeTenants: ['tenant_free', 'tenant_trial'],
group: 'premium'
)]
#[ORM\Entity]
#[ORM\Table(name: 'premium_feature')]
class PremiumFeature
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column(type: 'integer')]
private ?int $id = null;
#[ORM\Column(type: 'string', length: 255)]
private string $featureName;
// ...getters/setters
}
// ──────────────────────────────────────────────
// Checking tenant access in your services
// ──────────────────────────────────────────────
namespace App\Service;
use Hakam\MultiTenancyBundle\Attribute\TenantShared;
use Hakam\MultiTenancyBundle\Context\TenantContextInterface;
class FeatureAccessService
{
public function __construct(
private readonly TenantContextInterface $tenantContext,
) {}
/**
* Check if the current tenant can access a shared entity.
*/
public function canAccess(string $entityClass): bool
{
$reflection = new \ReflectionClass($entityClass);
$attributes = $reflection->getAttributes(TenantShared::class);
if (empty($attributes)) {
return true; // Not a shared entity — always accessible
}
$tenantShared = $attributes[0]->newInstance();
$tenantId = $this->tenantContext->getTenantId();
if ($tenantId === null) {
return false;
}
return $tenantShared->isAvailableForTenant($tenantId);
}
}