100 lines
2.9 KiB
PHP
100 lines
2.9 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Actions\Common;
|
|
|
|
use App\Contracts\Action;
|
|
use App\Contracts\ActionInput;
|
|
use App\Enums\MassActionType;
|
|
use App\Interfaces\ModelWithStar;
|
|
use App\Interfaces\ModelWithStatus;
|
|
use Illuminate\Database\Eloquent\Model;
|
|
use Webmozart\Assert\Assert;
|
|
|
|
/**
|
|
* @implements \App\Contracts\Action<\App\Actions\Common\ExecuteMassActionInput, int>
|
|
*/
|
|
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<Model> $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;
|
|
}
|
|
}
|