'array', 'modify_log' => 'array', ]; /* ===================== * Relationships * ===================== */ public function authInfo(): HasOne { return $this->hasOne(MemAuthInfo::class, 'mem_no', 'mem_no'); } public function authRows(): HasMany { // mem_auth 복합키 테이블이어도 조회 관계는 가능 return $this->hasMany(MemAuth::class, 'mem_no', 'mem_no'); } public function authLogs(): HasMany { return $this->hasMany(MemAuthLog::class, 'mem_no', 'mem_no'); } public function addresses(): HasMany { return $this->hasMany(MemAddress::class, 'mem_no', 'mem_no'); } public function joinLogs(): HasMany { return $this->hasMany(MemJoinLog::class, 'mem_no', 'mem_no'); } public function stRing(): HasOne { return $this->hasOne(MemStRing::class, 'mem_no', 'mem_no'); } public function loginRecents(): HasMany { return $this->hasMany(MemLoginRecent::class, 'mem_no', 'mem_no'); } public function modLogs(): HasMany { return $this->hasMany(MemModLog::class, 'mem_no', 'mem_no'); } /* ===================== * Scopes (기존 App\Models\MemInfo에서 가져옴) * ===================== */ public function scopeActive(Builder $q): Builder { // CI에서 stat_3 == 3 접근금지 / 4 탈퇴신청 / 5 탈퇴완료 return $q->whereNotIn('stat_3', ['3','4','5']); } public function scopeByEmail(Builder $q, string $email): Builder { return $q->where('email', strtolower($email)); } public function scopeByPhoneLookup(Builder $q, string $phoneNormalized): Builder { // TODO: cell_phone이 암호화면 단순 where 비교 불가 // 추천: cell_phone_hash 같은 정규화+해시 컬럼 만들어 lookup return $q; } /* ===================== * Helpers (둘 모델 통합) * ===================== */ public function isBlocked(): bool { return (string) $this->stat_3 === '3'; } public function isWithdrawnOrRequested(): bool { return in_array((string) $this->stat_3, ['4','5'], true); } public function isWithdrawn(): bool { // legacy: dt_out 기본값이 0000-00-00 00:00:00 일 수 있음 $v = $this->attributes['dt_out'] ?? null; return !empty($v) && $v !== '0000-00-00 00:00:00'; } public function hasEmail(): bool { return !empty($this->attributes['email']); } public function isFirstLogin(): bool { $dtLogin = $this->dt_login_at(); $dtReg = $this->dt_reg_at(); if (!$dtLogin || !$dtReg) return false; return $dtLogin->equalTo($dtReg); } /* ===================== * Safe datetime accessors * ===================== */ private function safeCarbon(?string $value): ?Carbon { if (!$value) return null; if ($value === '0000-00-00 00:00:00' || $value === '0000-00-00') return null; try { return Carbon::parse($value); } catch (\Throwable $e) { return null; } } public function dt_login_at(): ?Carbon { return $this->safeCarbon($this->attributes['dt_login'] ?? null); } public function dt_reg_at(): ?Carbon { return $this->safeCarbon($this->attributes['dt_reg'] ?? null); } public function dt_mod_at(): ?Carbon { return $this->safeCarbon($this->attributes['dt_mod'] ?? null); } }