*/ use BumpsContentVersion, HasContentViews, HasFactory, HasImages, HasRevisions, HasTranslations, SoftDeletes; /** @var array */ public array $translatable = ['headline', 'bio']; protected function casts(): array { return [ 'links' => 'array', 'is_public' => 'boolean', 'is_founder' => 'boolean', 'joined_at' => 'date', 'left_at' => 'date', 'position' => 'integer', ]; } /** * @return array */ public function imageAttributes(): array { return ['avatar']; } /** * @return BelongsTo */ public function avatarMedia(): BelongsTo { return $this->imageRelation('avatar'); } /** * A portrait's description is the person's name, so there is no separate * field for it: one that had to be typed would only ever be typed wrong. */ public function avatarAlt(): string { return $this->name; } /** * @return BelongsTo */ public function user(): BelongsTo { return $this->belongsTo(User::class); } /** * @return BelongsToMany */ public function technologies(): BelongsToMany { return $this->belongsToMany(Technology::class); } /** * @return BelongsToMany */ public function projects(): BelongsToMany { return $this->belongsToMany(Project::class)->withPivot('role'); } /** * @return HasMany */ public function talks(): HasMany { return $this->hasMany(Talk::class); } /** * @return HasMany */ public function ledProjects(): HasMany { return $this->hasMany(Project::class, 'lead_member_id'); } /** * Someone who has not left the collective. */ public function isActive(): bool { return $this->left_at === null; } /** * @param Builder<$this> $query * @return Builder<$this> */ public function scopePublic(Builder $query): Builder { return $query->where('is_public', true); } /** * @param Builder<$this> $query * @return Builder<$this> */ public function scopeCurrent(Builder $query): Builder { return $query->whereNull('left_at'); } }