*/ final class ExecuteMassAction implements Action { /** * @param \App\Actions\Common\ExecuteMassActionInput $input */ #[\Override] public function __invoke(ActionInput $input): int { Assert::isInstanceOf($input, ExecuteMassActionInput::class); $this->assertModelMatchesInput($input); return $this->updateModel($input); } private function assertModelMatchesInput(ExecuteMassActionInput $input): void { $modelClass = $input->modelClass; switch ($input->action) { case MassActionType::Star: case MassActionType::Unstar: Assert::isAOf($modelClass, ModelWithStar::class); break; case MassActionType::Publish: case MassActionType::Unpublish: Assert::isAOf($modelClass, ModelWithStatus::class); break; default: throw new \UnexpectedValueException('Unsupported mass action type: ' . $input->action->value); } } private function updateModel(ExecuteMassActionInput $input): int { $modelClass = $input->modelClass; /** @var class-string $modelClass */ $model = new $modelClass(); $models = $modelClass::query() ->whereIn($model->getKeyName(), $input->modelKeyList) ->get(); $updated = 0; foreach ($models as $foundModel) { if (! $foundModel instanceof Model) { continue; } switch ($input->action) { case MassActionType::Star: /** @var Model&ModelWithStar $foundModel */ $foundModel->setStar(true); break; case MassActionType::Unstar: /** @var Model&ModelWithStar $foundModel */ $foundModel->setStar(false); break; case MassActionType::Publish: /** @var Model&ModelWithStatus $foundModel */ $foundModel->setStatus(true); break; case MassActionType::Unpublish: /** @var Model&ModelWithStatus $foundModel */ $foundModel->setStatus(false); break; default: throw new \UnexpectedValueException('Unsupported mass action type: ' . $input->action->value); } $foundModel->saveOrFail(); $updated++; } return $updated; } }