Files
cattr/app/Models/Project.php
Noor E Ilahi 7ccf44f7da first commit
2026-01-09 12:54:53 +05:30

206 lines
6.4 KiB
PHP

<?php
namespace App\Models;
use App\Enums\ScreenshotsState;
use App\Scopes\ProjectAccessScope;
use App\Traits\ExposePermissions;
use Database\Factories\ProjectFactory;
use DB;
use Eloquent as EloquentIdeHelper;
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasManyThrough;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Database\Eloquent\Relations\MorphMany;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Query\Builder as QueryBuilder;
use Illuminate\Support\Carbon;
/**
* App\Models\Project
*
* @property int $id
* @property int|null $company_id
* @property string $name
* @property string $description
* @property Carbon|null $deleted_at
* @property Carbon|null $created_at
* @property Carbon|null $updated_at
* @property int $important
* @property string $source
* @property int|null $default_priority_id
* @property ScreenshotsState $screenshots_state
* @property-read Priority|null $defaultPriority
* @property-read array $can
* @property-read int|null $roles_count
* @property-read Collection|Status[] $statuses
* @property-read int|null $statuses_count
* @property-read Collection|Task[] $tasks
* @property-read ProjectPhase[] $phases
* @property-read int|null $tasks_count
* @property-read Collection|User[] $users
* @property-read int|null $users_count
* @method static ProjectFactory factory(...$parameters)
* @method static EloquentBuilder|Project newModelQuery()
* @method static EloquentBuilder|Project newQuery()
* @method static QueryBuilder|Project onlyTrashed()
* @method static EloquentBuilder|Project query()
* @method static EloquentBuilder|Project whereCompanyId($value)
* @method static EloquentBuilder|Project whereCreatedAt($value)
* @method static EloquentBuilder|Project whereDefaultPriorityId($value)
* @method static EloquentBuilder|Project whereDeletedAt($value)
* @method static EloquentBuilder|Project whereDescription($value)
* @method static EloquentBuilder|Project whereId($value)
* @method static EloquentBuilder|Project whereImportant($value)
* @method static EloquentBuilder|Project whereName($value)
* @method static EloquentBuilder|Project whereSource($value)
* @method static EloquentBuilder|Project whereUpdatedAt($value)
* @method static QueryBuilder|Project withTrashed()
* @method static QueryBuilder|Project withoutTrashed()
* @mixin EloquentIdeHelper
* @property-read Collection|Property[] $properties
* @property-read int|null $properties_count
*/
class Project extends Model
{
use SoftDeletes;
use ExposePermissions;
use HasFactory;
/**
* @var array
*/
protected $fillable = [
'company_id',
'name',
'description',
'important',
'source',
'default_priority_id',
'screenshots_state',
'group',
];
/**
* @var array
*/
protected $casts = [
'company_id' => 'integer',
'name' => 'string',
'description' => 'string',
'important' => 'integer',
'source' => 'string',
'default_priority_id' => 'integer',
];
/**
* @var array
*/
protected $dates = [
'deleted_at',
'created_at',
'updated_at',
];
protected const PERMISSIONS = ['update', 'update_members', 'destroy'];
protected static function boot(): void
{
parent::boot();
static::addGlobalScope(new ProjectAccessScope);
static::deleting(static function (Project $project) {
CronTaskWorkers::whereHas(
'task',
static fn(EloquentBuilder $query) => $query
->where('project_id', '=', $project->id)
)->delete();
$project->tasks()->delete();
});
}
public function tasks(): HasMany
{
return $this->hasMany(Task::class, 'project_id');
}
public function phases(): HasMany
{
return $this->hasMany(ProjectPhase::class);
}
public function users(): BelongsToMany
{
return $this->belongsToMany(User::class, 'projects_users')
->withPivot('role_id')
->using(ProjectUserPivot::class)
->withoutGlobalScopes();
}
public function group(): BelongsTo
{
return $this->belongsTo(ProjectGroup::class, 'group');
}
public function defaultPriority(): HasOne
{
return $this->hasOne(Priority::class, 'id', 'default_priority_id');
}
public function statuses(): BelongsToMany
{
return $this->belongsToMany(Status::class, 'projects_statuses', 'project_id', 'status_id')->withPivot('color');
}
public function getNameAttribute(): string
{
return empty($this->attributes['source']) || $this->attributes['source'] === 'internal'
? $this->attributes['name']
: ucfirst($this->attributes['source']) . ": {$this->attributes['name']}";
}
public function properties(): MorphMany
{
return $this->morphMany(Property::class, 'entity');
}
public function workers(): HasManyThrough
{
return $this->hasManyThrough(CronTaskWorkers::class, Task::class);
}
public function tasksRelations(): Attribute
{
$tasksIdsQuery = $this->tasks()->select('id');
return Attribute::make(get: fn() => DB::table('tasks_relations')
->whereIn('parent_id', $tasksIdsQuery)
->orWhereIn('child_id', $tasksIdsQuery)
->get(['parent_id', 'child_id']))->shouldCache();
}
protected function screenshotsState(): Attribute
{
return Attribute::make(
get: static function ($value): ScreenshotsState {
$projectState = ScreenshotsState::withGlobalOverrides($value);
return match ($projectState) {
null => ScreenshotsState::REQUIRED,
ScreenshotsState::ANY => ScreenshotsState::OPTIONAL,
default => $projectState,
};
},
set: static fn ($value) => (string)ScreenshotsState::getNormalizedValue($value),
)->shouldCache();
}
}