tenancy
tenancy copied to clipboard
[4.x] Add feature that allow to determine when model is syncable (after #915)
Sometimes is necessary to ignore resource synchronization.
In my case, i have contacts in tenant tables and these contacts can be or not an user. This way, i want to synchronize with central only contacts that contains email attribute defined.
Using the example bellow:
// Contact represents a tenant user
class Contact extends Authenticatable implements Syncable
{
use HasFactory,
ResourceSyncing;
/**
* The attributes that are mass assignable.
*
* @var array<int, string>
*/
protected $fillable = [
'name',
'email',
'password'
];
/**
* The attributes that should be hidden for arrays.
*
* @var array<int, string>
*/
protected $hidden = [
'password',
'api_token'
];
/**
* The global identifier key value
*
* @return string
*/
public function getGlobalIdentifierKey()
{
return $this->getAttribute($this->getGlobalIdentifierKeyName());
}
/**
* The global identifier key name
*
* @return string
*/
public function getGlobalIdentifierKeyName(): string
{
return 'email';
}
/**
* The central model class
*
* @return string
*/
public function getCentralModelName(): string
{
return CentralUser::class;
}
/**
* The synced attribute names
*
* @return array
*/
public function getSyncedAttributeNames(): array
{
return [
'name',
'password',
];
}
/**
* Synchronize only contacts that have email attribute defined
*
* @return bool
*/
public function isSyncEnabled(): bool
{
return $this->email !== null;
}
class CentralUser extends Authenticatable implements MustVerifyEmail, SyncMaster
{
use HasApiTokens,
HasFactory,
Notifiable,
ResourceSyncing,
CentralConnection;
/**
* The attributes that are mass assignable.
*
* @var array<int, string>
*/
protected $fillable = [
'name',
'email',
'password',
];
/**
* The attributes that should be hidden for serialization.
*
* @var array<int, string>
*/
protected $hidden = [
'password',
'remember_token',
];
/**
* The attributes that should be cast.
*
* @var array<string, string>
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
/**
* The users relationship definition
*
* @return BelongsToMany
*/
public function tenants(): BelongsToMany
{
return $this->belongsToMany(Tenant::class, 'tenant_users', 'email', 'tenant_id', 'email')
->using(TenantPivot::class);
}
/**
* The global identifier key value
*
* @return string
*/
public function getGlobalIdentifierKey()
{
return $this->getAttribute($this->getGlobalIdentifierKeyName());
}
/**
* The global identifier key name
*
* @return string
*/
public function getGlobalIdentifierKeyName(): string
{
return 'email';
}
/**
* The central model class
*
* @return string
*/
public function getCentralModelName(): string
{
return static::class;
}
/**
* The tenant model class
*
* @return string
*/
public function getTenantModelName(): string
{
return Contact::class;
}
/**
* The synced attribute names
*
* @return array
*/
public function getSyncedAttributeNames(): array
{
return [
'name',
'password'
];
}
}
Using:
$user = CentralUser::create([
'name' => 'Steve',
'email' => '[email protected]'
]);
$user = CentralUser::create([
'name' => 'Bill',
'email' => '[email protected]'
]);
// it will not be synced
$contact = Contact::create([
'name' => 'Steve Jobs'
]);
//it will be synced
$contact = Contact::create([
'name' => 'Bill Gates',
'email' => '[email protected]'
]);
The same logic can be applyed with central user.
With this PR, is possible to determine a "kind" of users (in my case contacts) must be synced