tenancy icon indicating copy to clipboard operation
tenancy copied to clipboard

[4.x] Add feature that allow to determine when model is syncable (after #915)

Open leandrogehlen opened this issue 3 years ago • 0 comments

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

leandrogehlen avatar Jul 04 '22 19:07 leandrogehlen