Proje dosyaları eklendi
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
<?php
|
||||
namespace App\Models;use Illuminate\Database\Eloquent\Model;
|
||||
class CompetitorAudit extends Model{protected$guarded=[];protected function casts():array{return['before'=>'array','after'=>'array'];}}
|
||||
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class EarnApiAccessLog extends Model
|
||||
{
|
||||
public $timestamps = false;
|
||||
|
||||
protected $guarded = [];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return ['occurred_at' => 'datetime', 'created_at' => 'datetime'];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Enums\EarnApiTokenStatus;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Laravel\Sanctum\PersonalAccessToken;
|
||||
|
||||
class EarnApiToken extends PersonalAccessToken
|
||||
{
|
||||
use SoftDeletes;
|
||||
|
||||
protected $table = 'personal_access_tokens';
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return array_merge(parent::casts(), [
|
||||
'is_active' => 'boolean', 'revoked_at' => 'datetime', 'deleted_at' => 'datetime',
|
||||
'device_bound_at' => 'datetime', 'last_seen_at' => 'datetime', 'device_mismatch_seen' => 'boolean',
|
||||
]);
|
||||
}
|
||||
|
||||
public function status(): EarnApiTokenStatus
|
||||
{
|
||||
if ($this->revoked_at !== null) {
|
||||
return EarnApiTokenStatus::Revoked;
|
||||
}
|
||||
if ($this->expires_at !== null && $this->expires_at->isPast()) {
|
||||
return EarnApiTokenStatus::Expired;
|
||||
}
|
||||
if (! $this->is_active) {
|
||||
return EarnApiTokenStatus::Inactive;
|
||||
}
|
||||
|
||||
return EarnApiTokenStatus::Active;
|
||||
}
|
||||
|
||||
public function canAccessTasks(): bool
|
||||
{
|
||||
return $this->status() === EarnApiTokenStatus::Active
|
||||
&& $this->can('tasks:read')
|
||||
&& $this->tokenable instanceof EarnMember
|
||||
&& $this->tokenable->canUseApi();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class EarnAudit extends Model
|
||||
{
|
||||
public $timestamps = false;
|
||||
|
||||
protected $guarded = [];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return ['metadata' => 'array', 'created_at' => 'datetime'];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Enums\EarnLegalDocumentType;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
class EarnLegalAcceptance extends Model
|
||||
{
|
||||
protected $guarded = [];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return ['document_type' => EarnLegalDocumentType::class, 'accepted_at' => 'datetime'];
|
||||
}
|
||||
|
||||
public function member(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(EarnMember::class, 'earn_member_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Enums\EarnMemberStatus;
|
||||
use App\Notifications\EarnVerifyEmail;
|
||||
use Illuminate\Contracts\Auth\MustVerifyEmail;
|
||||
use Illuminate\Database\Eloquent\Attributes\Fillable;
|
||||
use Illuminate\Database\Eloquent\Attributes\Hidden;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||
use Illuminate\Notifications\Notifiable;
|
||||
use Illuminate\Support\Str;
|
||||
use Laravel\Sanctum\HasApiTokens;
|
||||
|
||||
#[Fillable(['name', 'email', 'password', 'status', 'email_verified_at', 'last_login_at', 'last_login_ip'])]
|
||||
#[Hidden(['password', 'remember_token'])]
|
||||
class EarnMember extends Authenticatable implements MustVerifyEmail
|
||||
{
|
||||
use HasApiTokens, HasFactory, Notifiable, SoftDeletes;
|
||||
|
||||
protected static function booted(): void
|
||||
{
|
||||
static::creating(function (self $member): void {
|
||||
$member->ulid ??= (string) Str::ulid();
|
||||
});
|
||||
}
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'password' => 'hashed',
|
||||
'status' => EarnMemberStatus::class,
|
||||
'email_verified_at' => 'datetime',
|
||||
'last_login_at' => 'datetime',
|
||||
];
|
||||
}
|
||||
|
||||
public function audits(): HasMany
|
||||
{
|
||||
return $this->hasMany(EarnAudit::class);
|
||||
}
|
||||
|
||||
public function legalAcceptances(): HasMany
|
||||
{
|
||||
return $this->hasMany(EarnLegalAcceptance::class);
|
||||
}
|
||||
|
||||
public function canUseApi(): bool
|
||||
{
|
||||
return ! $this->trashed() && $this->status === EarnMemberStatus::Active && $this->hasVerifiedEmail();
|
||||
}
|
||||
|
||||
public function sendEmailVerificationNotification(): void
|
||||
{
|
||||
$this->notify(new EarnVerifyEmail);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasOne;
|
||||
|
||||
class EarnTaskAssignment extends Model
|
||||
{
|
||||
protected $guarded = [];
|
||||
|
||||
/**
|
||||
* Atamanın gerçek müşteri sahibini döndürür.
|
||||
*
|
||||
* @author Gökhan Engin - İletişim : https://bit.ly/YazılımUzmanı
|
||||
*/
|
||||
public function user(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Atama için kabul edilmiş tek idempotent sonucu döndürür.
|
||||
*
|
||||
* @author Gökhan Engin - İletişim : https://bit.ly/YazılımUzmanı
|
||||
*/
|
||||
public function result(): HasOne
|
||||
{
|
||||
return $this->hasOne(EarnTaskResult::class);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
class EarnTaskResult extends Model
|
||||
{
|
||||
protected $guarded = [];
|
||||
|
||||
/**
|
||||
* Sonucun sunucu tarafından doğrulanmış görev atamasını döndürür.
|
||||
*
|
||||
* @author Gökhan Engin - İletişim : https://bit.ly/YazılımUzmanı
|
||||
*/
|
||||
public function assignment(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(EarnTaskAssignment::class, 'earn_task_assignment_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* Sonucun ait olduğu normal müşteri kullanıcısını döndürür.
|
||||
*
|
||||
* @author Gökhan Engin - İletişim : https://bit.ly/YazılımUzmanı
|
||||
*/
|
||||
public function user(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sonuç alanlarını güvenli PHP türlerine dönüştürür.
|
||||
*
|
||||
* @return array<string, string>
|
||||
*
|
||||
* @author Gökhan Engin - İletişim : https://bit.ly/YazılımUzmanı
|
||||
*/
|
||||
protected function casts(): array
|
||||
{
|
||||
return ['completed' => 'boolean', 'submitted_at' => 'datetime'];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
<?php
|
||||
namespace App\Models;
|
||||
use App\Enums\{CheckFrequency,KeywordDevice,KeywordStatus,SearchEngine};use Illuminate\Database\Eloquent\{Builder,Model};use Illuminate\Database\Eloquent\Concerns\HasUlids;use Illuminate\Database\Eloquent\Factories\HasFactory;use Illuminate\Database\Eloquent\Relations\{BelongsTo,HasMany};
|
||||
class Keyword extends Model {use HasFactory,HasUlids;protected $fillable=['phrase','normalized_phrase','search_engine','country_code','language_code','device'];protected function casts():array{return ['search_engine'=>SearchEngine::class,'device'=>KeywordDevice::class,'status'=>KeywordStatus::class,'archived_at'=>'datetime','tracking_enabled'=>'boolean','check_frequency'=>CheckFrequency::class,'next_check_at'=>'datetime','last_queued_at'=>'datetime'];}public function uniqueIds():array{return ['ulid'];}public function getRouteKeyName():string{return 'ulid';}public function project():BelongsTo{return $this->belongsTo(Project::class);}public function serpChecks():HasMany{return $this->hasMany(SerpCheck::class);}public function scopeForProject(Builder $q,Project|int $p):Builder{return $q->where('project_id',$p instanceof Project?$p->id:$p);}public function scopeActive(Builder $q):Builder{return $q->where('status',KeywordStatus::Active)->whereNull('archived_at');}public function scopeArchived(Builder $q):Builder{return $q->where('status',KeywordStatus::Archived)->whereNotNull('archived_at');}public function archive():bool{return $this->forceFill(['status'=>KeywordStatus::Archived,'archived_at'=>now()])->save();}public function restoreKeyword():bool{return $this->forceFill(['status'=>KeywordStatus::Active,'archived_at'=>null])->save();}}
|
||||
@@ -0,0 +1,3 @@
|
||||
<?php
|
||||
namespace App\Models;use Illuminate\Database\Eloquent\Model;
|
||||
class KeywordAudit extends Model{protected $guarded=[];protected function casts():array{return ['before'=>'array','after'=>'array'];}}
|
||||
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||
|
||||
class Permission extends Model
|
||||
{
|
||||
protected $fillable = ['name', 'label'];
|
||||
public function roles(): BelongsToMany { return $this->belongsToMany(Role::class)->withTimestamps(); }
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
<?php
|
||||
namespace App\Models;use Illuminate\Database\Eloquent\Model;
|
||||
class ProfileAudit extends Model{protected$guarded=[];protected function casts():array{return['before'=>'array','after'=>'array'];}}
|
||||
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Enums\ProjectStatus;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Concerns\HasUlids;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
|
||||
class Project extends Model
|
||||
{
|
||||
use HasFactory, HasUlids;
|
||||
|
||||
protected $fillable = ['name', 'domain', 'url'];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return ['status' => ProjectStatus::class, 'archived_at' => 'datetime'];
|
||||
}
|
||||
|
||||
public function uniqueIds(): array { return ['ulid']; }
|
||||
public function getRouteKeyName(): string { return 'ulid'; }
|
||||
public function user(): BelongsTo { return $this->belongsTo(User::class); }
|
||||
public function owner(): BelongsTo { return $this->user(); }
|
||||
public function keywords(): HasMany { return $this->hasMany(Keyword::class); }
|
||||
public function competitors(): HasMany { return $this->hasMany(ProjectCompetitor::class); }
|
||||
public function scopeOwnedBy(Builder $query, User|int $owner): Builder
|
||||
{
|
||||
return $query->where('user_id', $owner instanceof User ? $owner->getKey() : $owner);
|
||||
}
|
||||
public function scopeActive(Builder $query): Builder
|
||||
{
|
||||
return $query->where('status', ProjectStatus::Active)->whereNull('archived_at');
|
||||
}
|
||||
public function archive(): bool
|
||||
{
|
||||
return $this->forceFill(['status' => ProjectStatus::Archived, 'archived_at' => now()])->save();
|
||||
}
|
||||
public function restoreProject(): bool
|
||||
{
|
||||
return $this->forceFill(['status' => ProjectStatus::Active, 'archived_at' => null])->save();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
<?php
|
||||
namespace App\Models;use Illuminate\Database\Eloquent\{Builder,Model};use Illuminate\Database\Eloquent\Concerns\HasUlids;use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
class ProjectCompetitor extends Model{use HasUlids;protected$fillable=['name','domain','normalized_domain','created_by'];protected function casts():array{return['archived_at'=>'datetime'];}public function uniqueIds():array{return['ulid'];}public function getRouteKeyName():string{return'ulid';}public function project():BelongsTo{return$this->belongsTo(Project::class);}public function creator():BelongsTo{return$this->belongsTo(User::class,'created_by');}public function scopeActive(Builder$q):Builder{return$q->where('status','active')->whereNull('archived_at');}}
|
||||
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||
|
||||
class Role extends Model
|
||||
{
|
||||
protected $fillable = ['name', 'label'];
|
||||
|
||||
public function permissions(): BelongsToMany { return $this->belongsToMany(Permission::class)->withTimestamps(); }
|
||||
public function users(): BelongsToMany { return $this->belongsToMany(User::class)->withTimestamps(); }
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
namespace App\Models;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
class RoleAssignmentAudit extends Model
|
||||
{
|
||||
protected $guarded = [];
|
||||
protected function casts(): array { return ['previous_roles'=>'array','new_roles'=>'array','added_roles'=>'array','removed_roles'=>'array']; }
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class SerpBudgetEntry extends Model
|
||||
{
|
||||
protected $guarded = [];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return ['reserved_at' => 'datetime', 'reconciled_at' => 'datetime'];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Enums\KeywordDevice;
|
||||
use App\Enums\SearchEngine;
|
||||
use App\Enums\SerpCheckStatus;
|
||||
use Illuminate\Database\Eloquent\Concerns\HasUlids;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use LogicException;
|
||||
|
||||
class SerpCheck extends Model
|
||||
{
|
||||
use HasFactory,HasUlids;
|
||||
|
||||
protected $guarded = ['id', 'keyword_id', 'ulid'];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return ['status' => SerpCheckStatus::class, 'search_engine' => SearchEngine::class, 'device' => KeywordDevice::class, 'checked_at' => 'datetime', 'started_at' => 'datetime', 'completed_at' => 'datetime', 'failed_at' => 'datetime', 'provider_task_posted_at' => 'datetime', 'provider_last_polled_at' => 'datetime', 'provider_next_poll_at' => 'datetime', 'provider_cost' => 'decimal:6'];
|
||||
}
|
||||
|
||||
public function uniqueIds(): array
|
||||
{
|
||||
return ['ulid'];
|
||||
}
|
||||
|
||||
public function getRouteKeyName(): string
|
||||
{
|
||||
return 'ulid';
|
||||
}
|
||||
|
||||
public function keyword(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Keyword::class);
|
||||
}
|
||||
|
||||
public function results(): HasMany
|
||||
{
|
||||
return $this->hasMany(SerpResult::class);
|
||||
}
|
||||
|
||||
public function begin(): bool
|
||||
{
|
||||
if ($this->status !== SerpCheckStatus::Pending) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->forceFill(['status' => SerpCheckStatus::Running, 'active_slot' => 'active', 'started_at' => now()])->save();
|
||||
}
|
||||
|
||||
public function complete(array $data): bool
|
||||
{
|
||||
if ($this->status !== SerpCheckStatus::Running) {
|
||||
throw new LogicException('Invalid check transition.');
|
||||
}
|
||||
|
||||
return $this->forceFill($data + ['status' => SerpCheckStatus::Completed, 'active_slot' => null, 'checked_at' => now(), 'completed_at' => now(), 'failed_at' => null, 'error_code' => null, 'error_message' => null])->save();
|
||||
}
|
||||
|
||||
public function fail(string $code, string $message): bool
|
||||
{
|
||||
if (! in_array($this->status, [SerpCheckStatus::Pending, SerpCheckStatus::Running], true)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->forceFill(['status' => SerpCheckStatus::Failed, 'active_slot' => null, 'failed_at' => now(), 'error_code' => $code, 'error_message' => $message])->save();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class SerpOperationAudit extends Model
|
||||
{
|
||||
protected $guarded = [];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return ['context' => 'array'];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class SerpOperationState extends Model
|
||||
{
|
||||
protected $guarded = [];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return ['emergency_stopped_at' => 'datetime', 'last_health_at' => 'datetime', 'last_provider_success_at' => 'datetime', 'ramp_started_at' => 'datetime'];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
<?php
|
||||
namespace App\Models;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
class SerpResult extends Model { use HasFactory; protected static function booted():void{static::saving(function(self $result):void{if($result->position<1)throw new \InvalidArgumentException('Position pozitif olmalıdır.');});} protected $guarded=[]; protected function casts():array{return ['is_project_domain'=>'boolean'];} public function serpCheck():BelongsTo{return $this->belongsTo(SerpCheck::class);} }
|
||||
@@ -0,0 +1,126 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Enums\RoleName;
|
||||
use App\Enums\UserStatus;
|
||||
use Database\Factories\UserFactory;
|
||||
use Filament\Models\Contracts\FilamentUser;
|
||||
use Filament\Panel;
|
||||
use Illuminate\Contracts\Auth\MustVerifyEmail;
|
||||
use Illuminate\Database\Eloquent\Attributes\Fillable;
|
||||
use Illuminate\Database\Eloquent\Attributes\Hidden;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\Relations\HasOne;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||
use Illuminate\Notifications\Notifiable;
|
||||
use Laravel\Sanctum\HasApiTokens;
|
||||
|
||||
#[Fillable(['name', 'email', 'password', 'locale', 'status'])]
|
||||
#[Hidden(['password', 'remember_token'])]
|
||||
class User extends Authenticatable implements FilamentUser, MustVerifyEmail
|
||||
{
|
||||
private const ADMIN_PORTAL_ROLES = [RoleName::SuperAdmin, RoleName::Admin];
|
||||
|
||||
/** @use HasFactory<UserFactory> */
|
||||
use HasApiTokens, HasFactory, Notifiable, SoftDeletes;
|
||||
|
||||
/**
|
||||
* Kullanıcı alanlarına uygulanacak güvenli tür dönüşümlerini tanımlar.
|
||||
*
|
||||
* @return array<string, string>
|
||||
*
|
||||
* @author Gökhan Engin - İletişim : https://bit.ly/YazılımUzmanı
|
||||
*/
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'email_verified_at' => 'datetime',
|
||||
'last_login_at' => 'datetime',
|
||||
'password' => 'hashed',
|
||||
'status' => UserStatus::class,
|
||||
];
|
||||
}
|
||||
|
||||
public function roles(): BelongsToMany
|
||||
{
|
||||
return $this->belongsToMany(Role::class)->withTimestamps()
|
||||
->orderByRaw("CASE roles.name WHEN 'super_admin' THEN 1 WHEN 'admin' THEN 2 WHEN 'support' THEN 3 WHEN 'customer' THEN 4 ELSE 5 END");
|
||||
}
|
||||
|
||||
public function projects(): HasMany
|
||||
{
|
||||
return $this->hasMany(Project::class);
|
||||
}
|
||||
|
||||
public function setting(): HasOne
|
||||
{
|
||||
return $this->hasOne(UserSetting::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Müşteriye sunucu tarafında bağlanmış görev sonuçlarını döndürür.
|
||||
*
|
||||
* @author Gökhan Engin - İletişim : https://bit.ly/YazılımUzmanı
|
||||
*/
|
||||
public function earnTaskResults(): HasMany
|
||||
{
|
||||
return $this->hasMany(EarnTaskResult::class);
|
||||
}
|
||||
|
||||
public function hasRole(RoleName|string $role): bool
|
||||
{
|
||||
$name = $role instanceof RoleName ? $role->value : $role;
|
||||
|
||||
return $this->roles()->where('name', $name)->exists();
|
||||
}
|
||||
|
||||
public function hasPermission(string $permission): bool
|
||||
{
|
||||
if ($this->hasRole(RoleName::SuperAdmin)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return $this->roles()->whereHas('permissions', fn ($query) => $query->where('name', $permission))->exists();
|
||||
}
|
||||
|
||||
public function isActive(): bool
|
||||
{
|
||||
return $this->status === UserStatus::Active;
|
||||
}
|
||||
|
||||
public function hasManagementRole(): bool
|
||||
{
|
||||
return $this->roles()->whereIn('name', array_map(
|
||||
static fn (RoleName $role): string => $role->value,
|
||||
self::ADMIN_PORTAL_ROLES,
|
||||
))->exists();
|
||||
}
|
||||
|
||||
/**
|
||||
* Kullanıcının diğer rollerinden bağımsız olarak müşteri paneline erişimini denetler.
|
||||
*
|
||||
* @return bool Aktif kullanıcı customer rolüne sahipse true.
|
||||
*
|
||||
* @author Gökhan Engin - İletişim : https://bit.ly/YazılımUzmanı
|
||||
*/
|
||||
public function canAccessCustomerPortal(): bool
|
||||
{
|
||||
return ! $this->trashed() && $this->isActive()
|
||||
&& $this->hasRole(RoleName::Customer);
|
||||
}
|
||||
|
||||
public function canAccessAdminPortal(): bool
|
||||
{
|
||||
return ! $this->trashed() && $this->isActive() && $this->hasVerifiedEmail()
|
||||
&& $this->hasManagementRole() && $this->hasPermission('admin.access');
|
||||
}
|
||||
|
||||
public function canAccessPanel(Panel $panel): bool
|
||||
{
|
||||
return $panel->getId() === 'admin' && $this->canAccessAdminPortal();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
<?php
|
||||
namespace App\Models;use Illuminate\Database\Eloquent\Model;use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
class UserSetting extends Model{protected$fillable=['theme','timezone','date_format','time_format','default_report_range','default_project_id','per_page','in_app_notifications','reduced_motion'];protected function casts():array{return['in_app_notifications'=>'boolean','reduced_motion'=>'boolean'];}public function user():BelongsTo{return$this->belongsTo(User::class);}public static function defaults():array{return['theme'=>'system','timezone'=>'Europe/Istanbul','date_format'=>'DD.MM.YYYY','time_format'=>'24','default_report_range'=>'30_days','default_project_id'=>null,'per_page'=>25,'in_app_notifications'=>true,'reduced_motion'=>false];}}
|
||||
Reference in New Issue
Block a user