69 lines
2.2 KiB
PHP
69 lines
2.2 KiB
PHP
<?php
|
|
|
|
namespace App\Polls;
|
|
|
|
use App\Polls\Contracts\QuestionType;
|
|
use InvalidArgumentException;
|
|
|
|
/**
|
|
* The question types enabled for this platform, read from 'polls.question_types'.
|
|
* Without that key (a platform config that has not merged the polls section yet)
|
|
* all built-in types are enabled; an empty list disables them on purpose.
|
|
*/
|
|
class QuestionTypeRegistry
|
|
{
|
|
public const DEFAULT_TYPES = [
|
|
'yes_no' => Types\YesNoType::class,
|
|
'yes_no_conditional' => Types\YesNoConditionalType::class,
|
|
'single_choice' => Types\SingleChoiceType::class,
|
|
'multi_choice' => Types\MultiChoiceType::class,
|
|
'date_time_slots' => Types\DateTimeSlotsType::class,
|
|
'scale' => Types\ScaleType::class,
|
|
'text' => Types\TextType::class,
|
|
'ranking' => Types\RankingType::class,
|
|
];
|
|
|
|
/** @var array<string, QuestionType>|null */
|
|
private ?array $types = null;
|
|
|
|
/** @return array<string, QuestionType> keyed by type key */
|
|
public function all(): array
|
|
{
|
|
if ($this->types === null) {
|
|
$this->types = [];
|
|
foreach (timebank_config('polls.question_types') ?? self::DEFAULT_TYPES as $key => $class) {
|
|
$type = app($class);
|
|
if (!$type instanceof QuestionType) {
|
|
throw new InvalidArgumentException("Poll question type [$key] must implement " . QuestionType::class);
|
|
}
|
|
if ($type->key() !== $key) {
|
|
throw new InvalidArgumentException("Poll question type [$key] reports key [{$type->key()}]");
|
|
}
|
|
$this->types[$key] = $type;
|
|
}
|
|
}
|
|
|
|
return $this->types;
|
|
}
|
|
|
|
public function has(string $key): bool
|
|
{
|
|
return isset($this->all()[$key]);
|
|
}
|
|
|
|
public function get(string $key): QuestionType
|
|
{
|
|
if (!$this->has($key)) {
|
|
throw new InvalidArgumentException("Unknown or disabled poll question type [$key]");
|
|
}
|
|
|
|
return $this->all()[$key];
|
|
}
|
|
|
|
/** @return array<string, string> key => translated label, for the editor's type select */
|
|
public function options(): array
|
|
{
|
|
return array_map(fn (QuestionType $type) => $type->label(), $this->all());
|
|
}
|
|
}
|