Files
animethemes-server/app/Actions/Models/User/Report/ReportAction.php
T
2025-10-01 17:18:31 -03:00

100 lines
3.5 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Actions\Models\User\Report;
use App\Enums\Models\User\ApprovableStatus;
use App\Enums\Models\User\ReportActionType;
use App\Models\User\Report;
use App\Models\User\Report\ReportStep;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\Pivot;
use Illuminate\Database\Eloquent\Relations\Relation;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Auth;
class ReportAction
{
/**
* Create a report with the given steps.
*
* @param ReportStep|ReportStep[] $steps
*/
public static function makeReport(ReportStep|array $steps, ?string $notes = null): Report
{
$report = Report::query()->create([
Report::ATTRIBUTE_USER => Auth::id(),
Report::ATTRIBUTE_STATUS => ApprovableStatus::PENDING->value,
Report::ATTRIBUTE_NOTES => $notes,
]);
$report->steps()->saveMany(Arr::wrap($steps));
return $report;
}
/**
* Create a report step to create a model.
*
* @param class-string<Model> $model
*/
public static function makeForCreate(string $model, array $fields): ReportStep
{
return static::makeFor(ReportActionType::CREATE, $model, $fields);
}
/**
* Create a report step to edit a model.
*/
public static function makeForUpdate(Model $model, array $fields): ReportStep
{
return static::makeFor(ReportActionType::UPDATE, $model, $fields);
}
/**
* Create a report step to delete a model.
*/
public static function makeForDelete(Model $model): ReportStep
{
return static::makeFor(ReportActionType::DELETE, $model);
}
/**
* Create a report step to attach a model to another in a many-to-many relationship.
*
* @param class-string<Pivot> $pivot
*/
public static function makeForAttach(Model $foreign, Model $related, string $pivot, array $fields): ReportStep
{
return static::makeFor(ReportActionType::ATTACH, $foreign, $fields, $related, $pivot);
}
/**
* Create a report step to detach a model from another in a many-to-many relationship.
*/
public static function makeForDetach(Model $foreign, Model $related, Pivot $pivot, array $fields): ReportStep
{
return static::makeFor(ReportActionType::DETACH, $foreign, $fields, $related, $pivot);
}
/**
* Create a report step for given action.
*
* @param class-string<Model>|Model $model
*/
protected static function makeFor(ReportActionType $action, Model|string $model, ?array $fields = null, ?Model $related = null, Pivot|string|null $pivot = null): ReportStep
{
return new ReportStep([
ReportStep::ATTRIBUTE_ACTION => $action->value,
ReportStep::ATTRIBUTE_ACTIONABLE_TYPE => $model instanceof Model ? Relation::getMorphAlias($model->getMorphClass()) : $model,
ReportStep::ATTRIBUTE_ACTIONABLE_ID => $model instanceof Model ? $model->getKey() : null,
ReportStep::ATTRIBUTE_FIELDS => Arr::where($fields, fn ($value, $key) => $model->isFillable($key)),
ReportStep::ATTRIBUTE_STATUS => ApprovableStatus::PENDING->value,
ReportStep::ATTRIBUTE_TARGET_TYPE => $related instanceof Model ? Relation::getMorphAlias($related->getMorphClass()) : null,
ReportStep::ATTRIBUTE_TARGET_ID => $related instanceof Model ? $related->getKey() : null,
ReportStep::ATTRIBUTE_PIVOT => $pivot instanceof Model ? Relation::getMorphAlias($pivot->getMorphClass()) : $pivot,
]);
}
}