diff --git a/modules/quiz_directions/src/Plugin/quiz/QuizQuestion/QuizDirectionsQuestion.php b/modules/quiz_directions/src/Plugin/quiz/QuizQuestion/QuizDirectionsQuestion.php index af5b7039dc29b243e1dee84d735ddc58f9a87820..cca479ca8197d692d5f77f84bac12e6d3880b886 100644 --- a/modules/quiz_directions/src/Plugin/quiz/QuizQuestion/QuizDirectionsQuestion.php +++ b/modules/quiz_directions/src/Plugin/quiz/QuizQuestion/QuizDirectionsQuestion.php @@ -3,11 +3,12 @@ namespace Drupal\quiz_directions\Plugin\quiz\QuizQuestion; use Drupal\Core\Form\FormStateInterface; +use Drupal\Core\StringTranslation\TranslatableMarkup; +use Drupal\quiz\Attribute\QuizQuestion as QuizQuestionAttribute; use Drupal\quiz\Entity\QuizQuestion; use Drupal\quiz\Entity\QuizResultAnswer; /** - * @file * Quiz_directions classes. * * This module uses the question interface to define something which is @@ -20,15 +21,12 @@ use Drupal\quiz\Entity\QuizResultAnswer; * please..." (Won't work if the question order is randomized); * - Final confirmation, e.g. "You have answered all questions. Click submit * to submit this quiz."; - * - * @QuizQuestion ( - * id = "directions", - * label = @Translation("Directions question"), - * handlers = { - * "response" = "\Drupal\quiz_directions\Plugin\quiz\QuizQuestion\QuizDirectionsResponse" - * } - * ) */ +#[QuizQuestionAttribute( + id: 'directions', + label: new TranslatableMarkup('Directions question'), + handlers: ['response' => QuizDirectionsResponse::class], +)] class QuizDirectionsQuestion extends QuizQuestion { /** diff --git a/modules/quiz_long_answer/src/Plugin/quiz/QuizQuestion/LongAnswerQuestion.php b/modules/quiz_long_answer/src/Plugin/quiz/QuizQuestion/LongAnswerQuestion.php index 670769dc19a4835135b01e3bcb191eb5850707eb..8648c3e30a6b93ce0f96b9cd4ccb471f6a94bac9 100644 --- a/modules/quiz_long_answer/src/Plugin/quiz/QuizQuestion/LongAnswerQuestion.php +++ b/modules/quiz_long_answer/src/Plugin/quiz/QuizQuestion/LongAnswerQuestion.php @@ -4,21 +4,20 @@ namespace Drupal\quiz_long_answer\Plugin\quiz\QuizQuestion; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\StringTranslation\StringTranslationTrait; +use Drupal\Core\StringTranslation\TranslatableMarkup; +use Drupal\quiz\Attribute\QuizQuestion as QuizQuestionAttribute; use Drupal\quiz\Entity\QuizQuestion; use Drupal\quiz\Entity\QuizResultAnswer; use function filter_default_format; /** * Long Answer Quiz Question. - * - * @QuizQuestion ( - * id = "long_answer", - * label = @Translation("Long answer question"), - * handlers = { - * "response" = "\Drupal\quiz_long_answer\Plugin\quiz\QuizQuestion\LongAnswerResponse" - * } - * ) */ +#[QuizQuestionAttribute( + id: 'Translation', + label: new TranslatableMarkup('Long answer question'), + handlers: ['response' => LongAnswerResponse::class], +)] class LongAnswerQuestion extends QuizQuestion { use StringTranslationTrait; diff --git a/modules/quiz_matching/src/Plugin/quiz/QuizQuestion/MatchingQuestion.php b/modules/quiz_matching/src/Plugin/quiz/QuizQuestion/MatchingQuestion.php index 841de577189031c563db7874ab4cb660fb02c613..3693882552cca5ebc7e2b65dfb709889ecd22c11 100644 --- a/modules/quiz_matching/src/Plugin/quiz/QuizQuestion/MatchingQuestion.php +++ b/modules/quiz_matching/src/Plugin/quiz/QuizQuestion/MatchingQuestion.php @@ -4,6 +4,8 @@ namespace Drupal\quiz_matching\Plugin\quiz\QuizQuestion; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\StringTranslation\StringTranslationTrait; +use Drupal\Core\StringTranslation\TranslatableMarkup; +use Drupal\quiz\Attribute\QuizQuestion as QuizQuestionAttribute; use Drupal\quiz\Entity\QuizQuestion; use Drupal\quiz\Entity\QuizResultAnswer; @@ -14,15 +16,12 @@ use Drupal\quiz\Entity\QuizResultAnswer; * * A Matching node defines a series of questions and answers and requires the * userto associate each answer with a question. - * - * @QuizQuestion ( - * id = "matching", - * label = @Translation("Matching question"), - * handlers = { - * "response" = "\Drupal\quiz_matching\Plugin\quiz\QuizQuestion\MatchingResponse" - * } - * ) */ +#[QuizQuestionAttribute( + id: 'matching', + label: new TranslatableMarkup('Matching question'), + handlers: ['response' => MatchingResponse::class], +)] class MatchingQuestion extends QuizQuestion { use StringTranslationTrait; diff --git a/modules/quiz_multichoice/src/Plugin/quiz/QuizQuestion/MultichoiceQuestion.php b/modules/quiz_multichoice/src/Plugin/quiz/QuizQuestion/MultichoiceQuestion.php index 54d81e2915ae885d204f94ab1c88534f014c1dbd..d8bbe070d08c8488ec59bc859c081e5add9958cd 100644 --- a/modules/quiz_multichoice/src/Plugin/quiz/QuizQuestion/MultichoiceQuestion.php +++ b/modules/quiz_multichoice/src/Plugin/quiz/QuizQuestion/MultichoiceQuestion.php @@ -4,22 +4,21 @@ namespace Drupal\quiz_multichoice\Plugin\quiz\QuizQuestion; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\StringTranslation\StringTranslationTrait; +use Drupal\Core\StringTranslation\TranslatableMarkup; use Drupal\Core\Url; +use Drupal\quiz\Attribute\QuizQuestion as QuizQuestionAttribute; use Drupal\quiz\Entity\QuizQuestion; use Drupal\quiz\Entity\QuizResultAnswer; use function check_markup; /** * Multichoice Question. - * - * @QuizQuestion ( - * id = "multichoice", - * label = @Translation("Multiple choice question"), - * handlers = { - * "response" = "\Drupal\quiz_multichoice\Plugin\quiz\QuizQuestion\MultichoiceResponse" - * } - * ) */ +#[QuizQuestionAttribute( + id: 'multichoice', + label: new TranslatableMarkup('Multiple choice question'), + handlers: ['response' => MultichoiceResponse::class], +)] class MultichoiceQuestion extends QuizQuestion { use StringTranslationTrait; diff --git a/modules/quiz_page/src/Plugin/quiz/QuizQuestion/QuizPageQuestion.php b/modules/quiz_page/src/Plugin/quiz/QuizQuestion/QuizPageQuestion.php index abc49bc6167e39d3458719eb90b5b52d5bf6b06a..021a5ac0373547e6a93c9aec149c367f4d57dd3c 100644 --- a/modules/quiz_page/src/Plugin/quiz/QuizQuestion/QuizPageQuestion.php +++ b/modules/quiz_page/src/Plugin/quiz/QuizQuestion/QuizPageQuestion.php @@ -3,6 +3,8 @@ namespace Drupal\quiz_page\Plugin\quiz\QuizQuestion; use Drupal\Core\Form\FormStateInterface; +use Drupal\Core\StringTranslation\TranslatableMarkup; +use Drupal\quiz\Attribute\QuizQuestion as QuizQuestionAttribute; use Drupal\quiz\Entity\QuizQuestion; use Drupal\quiz\Entity\QuizResultAnswer; @@ -14,25 +16,21 @@ use Drupal\quiz\Entity\QuizResultAnswer; * * A Quiz page node is a placeholder for presenting multiple questions * on the same page. - * - * @QuizQuestion ( - * id = "page", - * label = @Translation("Quiz page"), - * handlers = { - * "response" = "\Drupal\quiz_page\Plugin\quiz\QuizQuestion\QuizPageResponse" - * } - * ) */ +#[QuizQuestionAttribute( + id: 'page', + label: new TranslatableMarkup('Quiz page'), + handlers: ['response' => QuizPageResponse::class], +)] class QuizPageQuestion extends QuizQuestion { /** * {@inheritdoc} */ public function getAnsweringForm(FormStateInterface $form_state, QuizResultAnswer $quizQuestionResultAnswer): array { - $element = [ + return [ '#type' => 'hidden', ]; - return $element; } /** @@ -40,7 +38,7 @@ class QuizPageQuestion extends QuizQuestion { * * @see QuizQuestion::getCreationForm() */ - public function getCreationForm(array &$form_state = NULL) { + public function getCreationForm(array &$form_state = NULL): array { return []; } diff --git a/modules/quiz_short_answer/src/Plugin/quiz/QuizQuestion/ShortAnswerQuestion.php b/modules/quiz_short_answer/src/Plugin/quiz/QuizQuestion/ShortAnswerQuestion.php index 1cfc8b1f409392869a5095f3ea5e1a36da485b41..b4384041033ba935cc2e0d3c125c9af4a0d00301 100644 --- a/modules/quiz_short_answer/src/Plugin/quiz/QuizQuestion/ShortAnswerQuestion.php +++ b/modules/quiz_short_answer/src/Plugin/quiz/QuizQuestion/ShortAnswerQuestion.php @@ -4,20 +4,19 @@ namespace Drupal\quiz_short_answer\Plugin\quiz\QuizQuestion; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\StringTranslation\StringTranslationTrait; +use Drupal\Core\StringTranslation\TranslatableMarkup; +use Drupal\quiz\Attribute\QuizQuestion as QuizQuestionAttribute; use Drupal\quiz\Entity\QuizQuestion; use Drupal\quiz\Entity\QuizResultAnswer; /** * Short answer question plugin. - * - * @QuizQuestion ( - * id = "short_answer", - * label = @Translation("Short answer question"), - * handlers = { - * "response" = "\Drupal\quiz_short_answer\Plugin\quiz\QuizQuestion\ShortAnswerResponse" - * } - * ) */ +#[QuizQuestionAttribute( + id: 'short_answer', + label: new TranslatableMarkup('Short answer question'), + handlers: ['response' => ShortAnswerResponse::class], +)] class ShortAnswerQuestion extends QuizQuestion { use StringTranslationTrait; diff --git a/modules/quiz_truefalse/src/Plugin/quiz/QuizQuestion/TrueFalseQuestion.php b/modules/quiz_truefalse/src/Plugin/quiz/QuizQuestion/TrueFalseQuestion.php index 2ba7fd3b824a11d841da90a3f348f15692f3b6e5..0c784af33fb8322e49f3324cca5464bc507d36b3 100644 --- a/modules/quiz_truefalse/src/Plugin/quiz/QuizQuestion/TrueFalseQuestion.php +++ b/modules/quiz_truefalse/src/Plugin/quiz/QuizQuestion/TrueFalseQuestion.php @@ -4,20 +4,19 @@ namespace Drupal\quiz_truefalse\Plugin\quiz\QuizQuestion; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\StringTranslation\StringTranslationTrait; +use Drupal\Core\StringTranslation\TranslatableMarkup; +use Drupal\quiz\Attribute\QuizQuestion as QuizQuestionAttribute; use Drupal\quiz\Entity\QuizQuestion; use Drupal\quiz\Entity\QuizResultAnswer; /** * The true/false question plugin. - * - * @QuizQuestion ( - * id = "truefalse", - * label = @Translation("True/false question"), - * handlers = { - * "response" = "\Drupal\quiz_truefalse\Plugin\quiz\QuizQuestion\TrueFalseResponse" - * } - * ) */ +#[QuizQuestionAttribute( + id: 'truefalse', + label: new TranslatableMarkup('True/false question'), + handlers: ['response' => TrueFalseResponse::class], +)] class TrueFalseQuestion extends QuizQuestion { use StringTranslationTrait; diff --git a/quiz.api.php b/quiz.api.php index 450a8bb2ae9c6b85c6f8e15724395458817ac40a..ee41b509dbe17bd5cc08edca6ab35f038b68cce2 100644 --- a/quiz.api.php +++ b/quiz.api.php @@ -9,9 +9,6 @@ use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Session\AccountInterface; /** - * @file quiz.api.php - * Hooks provided by Quiz module. - * * These entity types provided by Quiz also have entity API hooks. There are a * few additional Quiz specific hooks defined in this file. * @@ -25,7 +22,8 @@ use Drupal\Core\Session\AccountInterface; * * hook_quiz_result_presave(QuizResult $quiz_result) * - Runs before a result is saved to the DB. - * hook_quiz_question_relationship_insert(QuizQuestionRelationship $quiz_question_relationship) + * hook_quiz_question_relationship_insert( + * QuizQuestionRelationship $quiz_question_relationship) * - Runs when a new question is added to a quiz. * * You can also use Rules to build conditional actions based off of these diff --git a/quiz.module b/quiz.module index 8c5c7befb88e457aebf687c92db768994f8e2d71..d68ed0639f179f7997e295a9d77c4b717fc23925 100644 --- a/quiz.module +++ b/quiz.module @@ -519,9 +519,9 @@ function quiz_get_feedback_options(): array { $feedback_options = Drupal::moduleHandler()->invokeAll('quiz_feedback_options'); $view_modes = Drupal::service('entity_display.repository')->getViewModes('quiz_question'); - $feedback_options["quiz_question_view_full"] = t('Question' . ': ' . 'Full'); + $feedback_options["quiz_question_view_full"] = t('Question: Full'); foreach ($view_modes as $view_mode => $info) { - $feedback_options["quiz_question_view_" . $view_mode] = t('Question' . ': ' . $info['label']); + $feedback_options["quiz_question_view_" . $view_mode] = t('Question: @label', ['@label' => $info['label']]); } $feedback_options += [ diff --git a/quiz.rules_defaults.inc b/quiz.rules_defaults.inc index 5d61297a1a8c5bacca924e676d903c52adfb7f56..e9f2ec7adb9eadc4e55d717d11bfe8d6af0b4932 100644 --- a/quiz.rules_defaults.inc +++ b/quiz.rules_defaults.inc @@ -2,7 +2,7 @@ /** * @file - * Used for interaction with rules module + * Used for interaction with rules module. * * @todo not entirely sure? */ diff --git a/src/Attribute/QuizQuestion.php b/src/Attribute/QuizQuestion.php new file mode 100644 index 0000000000000000000000000000000000000000..c3e58fbd287e9bb78086431495d246fa3191ce3b --- /dev/null +++ b/src/Attribute/QuizQuestion.php @@ -0,0 +1,41 @@ +<?php + +declare(strict_types=1); + +namespace Drupal\quiz\Attribute; + +use Drupal\Component\Plugin\Attribute\Plugin; +use Drupal\Core\StringTranslation\TranslatableMarkup; + +/** + * Defines a Plugin attribute class for quiz questions. + * + * @see QuizQuestionPluginManager + * @see plugin_api + * + * @ingroup quiz + */ +#[\Attribute(\Attribute::TARGET_CLASS)] +class QuizQuestion extends Plugin { + + /** + * Constructs a QuizQuestion attribute. + * + * @param string $id + * The plugin ID. + * @param \Drupal\Core\StringTranslation\TranslatableMarkup|null $label + * The label of the plugin. + * @param array $handlers + * Array handlers for the question. + * @param class-string|null $deriver + * (optional) The deriver class. + */ + public function __construct( + public readonly string $id, + public readonly ?TranslatableMarkup $label = NULL, + protected readonly array $handlers = [], + public readonly ?string $deriver = NULL, + ) { + } + +} diff --git a/src/Entity/QuizFeedbackType.php b/src/Entity/QuizFeedbackType.php index 77931b90718d401eca8ca1531736506ab94265fc..1e0039aec409925684a9e6e5c924974909126394 100644 --- a/src/Entity/QuizFeedbackType.php +++ b/src/Entity/QuizFeedbackType.php @@ -54,7 +54,7 @@ class QuizFeedbackType extends ConfigEntityBase implements RulesUiComponentProvi /** * {@inheritdoc} */ - public function getComponent() { + public function getComponent(): RulesComponent { if (empty($this->component)) { // Provide a default for now. // @todo make expression configurable. diff --git a/src/Entity/QuizQuestion.php b/src/Entity/QuizQuestion.php index 62406362f84088eef11718988b8a0b21570a744c..9056f6a7a3efa11eb585381f33d17a8321a053ac 100644 --- a/src/Entity/QuizQuestion.php +++ b/src/Entity/QuizQuestion.php @@ -69,7 +69,7 @@ use Drupal\user\EntityOwnerTrait; * } * ) */ -abstract class QuizQuestion extends EditorialContentEntityBase implements QuizQuestionInterface, EntityOwnerInterface { +class QuizQuestion extends EditorialContentEntityBase implements QuizQuestionInterface, EntityOwnerInterface { /** * Define question statuses... @@ -141,4 +141,11 @@ abstract class QuizQuestion extends EditorialContentEntityBase implements QuizQu return parent::save(); } + /** + * @return int + */ + public function getMaximumScore(): int { + return 0; + } + } diff --git a/src/Entity/QuizQuestionBroken.php b/src/Entity/QuizQuestionBroken.php index e3a8efed5f1171fae9c30e0b05f09dce83631295..dd73182b596d1426380e9208753d00cb7b4cc1d4 100644 --- a/src/Entity/QuizQuestionBroken.php +++ b/src/Entity/QuizQuestionBroken.php @@ -7,11 +7,4 @@ namespace Drupal\quiz\Entity; */ class QuizQuestionBroken extends QuizQuestion { - /** - * - */ - public function getMaximumScore(): int { - return 0; - } - } diff --git a/src/Entity/QuizResultAnswer.php b/src/Entity/QuizResultAnswer.php index 27b7dded76f54bcf01eb74bc4b91afaa69dca9bb..34f75ead5b0d27875ffc2841efa14fa90a2e8f05 100644 --- a/src/Entity/QuizResultAnswer.php +++ b/src/Entity/QuizResultAnswer.php @@ -50,7 +50,7 @@ use Drupal\quiz\QuizAnswerInterface; * } * ) */ -abstract class QuizResultAnswer extends ContentEntityBase implements QuizAnswerInterface { +class QuizResultAnswer extends ContentEntityBase implements QuizAnswerInterface { use QuizResultAnswerEntityTrait; @@ -158,7 +158,7 @@ abstract class QuizResultAnswer extends ContentEntityBase implements QuizAnswerI /** * {@inheritdoc} * - * Quiz result answers are never viewed outside of a Quiz result, so we + * Quiz result answers are never viewed outside a Quiz result, so we * enforce that a Quiz result route parameter is added. */ public function toUrl($rel = 'canonical', array $options = []) { @@ -168,4 +168,18 @@ abstract class QuizResultAnswer extends ContentEntityBase implements QuizAnswerI return $url; } + /** + * {@inheritdoc} + */ + public function score(array $values): ?int { + return NULL; + } + + /** + * {@inheritdoc} + */ + public function getResponse() { + return NULL; + } + } diff --git a/src/Entity/QuizResultAnswerEntityTrait.php b/src/Entity/QuizResultAnswerEntityTrait.php index 39574b411c860e5d7db8f0fd5e1c0017e9951d91..f61ae7123be3c32cb4e21238c6e1c0c6cfe38785 100644 --- a/src/Entity/QuizResultAnswerEntityTrait.php +++ b/src/Entity/QuizResultAnswerEntityTrait.php @@ -93,7 +93,6 @@ trait QuizResultAnswerEntityTrait { if ($quiz->get('randomization')->getString() == 3) { /** @var Drupal\paragraphs\Entity\Paragraph[] $terms */ $terms = $quiz->get('quiz_terms')->referencedEntities(); - $total_questions = []; foreach ($terms as $term) { if ($term->get('quiz_question_tid')->getString() == $this->get('tid')->getString()) { return $term->get('quiz_question_max_score')->getString(); diff --git a/src/Entity/QuizViewsData.php b/src/Entity/QuizViewsData.php index d80c4bfd98201070fa6fde291fb172fcd425ab99..d1fb7337981df82db57a59670e32d777132719f2 100644 --- a/src/Entity/QuizViewsData.php +++ b/src/Entity/QuizViewsData.php @@ -17,7 +17,7 @@ class QuizViewsData extends EntityViewsData { * * @todo Cleanup once https://www.drupal.org/node/2489476 lands. */ - public function getViewsData() { + public function getViewsData(): array { $data = parent::getViewsData(); foreach (['quiz', 'quiz_revision'] as $table) { diff --git a/src/Plugin/QuizQuestionPluginManager.php b/src/Plugin/QuizQuestionPluginManager.php index aee2858dc0232340136e3150160cb60d5be03312..9a06c56b5dbbb1e64c38cad7fe8bc551b3861e93 100644 --- a/src/Plugin/QuizQuestionPluginManager.php +++ b/src/Plugin/QuizQuestionPluginManager.php @@ -5,8 +5,7 @@ namespace Drupal\quiz\Plugin; use Drupal\Core\Cache\CacheBackendInterface; use Drupal\Core\Extension\ModuleHandlerInterface; use Drupal\Core\Plugin\DefaultPluginManager; -use Drupal\quiz\Annotation\QuizQuestion; - +use Drupal\quiz\Attribute\QuizQuestion; /** * Provides the Quiz Question plugin manager. */ @@ -24,7 +23,7 @@ class QuizQuestionPluginManager extends DefaultPluginManager { * The module handler to invoke the alter hook with. */ public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler) { - parent::__construct('Plugin/quiz', $namespaces, $module_handler, QuizQuestionInterface::class, QuizQuestion::class); + parent::__construct('Plugin/quiz', $namespaces, $module_handler, QuizQuestionInterface::class, QuizQuestion::class, 'Drupal\quiz\Annotation\QuizQuestion'); $this->alterInfo('quiz_question_info'); $this->setCacheBackend($cache_backend, 'quiz_question_plugins'); diff --git a/src/Entity/QuizResultListBuilder.php b/src/QuizResultListBuilder.php similarity index 86% rename from src/Entity/QuizResultListBuilder.php rename to src/QuizResultListBuilder.php index 59993c6ce4fab626e09b0973e9ec055a58f09313..65be8cc2a64df772bb55eef7b22018b332951723 100644 --- a/src/Entity/QuizResultListBuilder.php +++ b/src/QuizResultListBuilder.php @@ -1,9 +1,10 @@ <?php -namespace Drupal\quiz\Entity; +namespace Drupal\quiz; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\EntityListBuilder; +use Drupal\quiz\Entity\QuizResult; /** * Defines the list builder for quiz results. @@ -13,7 +14,7 @@ class QuizResultListBuilder extends EntityListBuilder { /** * {@inheritdoc} */ - public function render() { + public function render(): array { $build = parent::render(); $build['table']['#caption'] = t('Quiz results.'); return $build; @@ -22,7 +23,7 @@ class QuizResultListBuilder extends EntityListBuilder { /** * {@inheritdoc} */ - public function buildHeader() { + public function buildHeader(): array { $header['quiz'] = $this->t('Quiz'); $header['user'] = $this->t('User'); return $header + parent::buildHeader(); diff --git a/tests/src/Functional/QuizEvaluationTest.php b/tests/src/Functional/QuizEvaluationTest.php index 15c888095a9a0cf7cb67a18a62368950ac8f875b..0ee346217fdb17a92d3fdf2bc7f9210bad3fbb9e 100644 --- a/tests/src/Functional/QuizEvaluationTest.php +++ b/tests/src/Functional/QuizEvaluationTest.php @@ -24,7 +24,7 @@ class QuizEvaluationTest extends QuizTestBase { /** * Test that a quiz result is marked as evaluated. */ - public function testQuizEvaluation() { + public function testQuizEvaluation(): void { $this->drupalLogin($this->admin); $quiz_node = $this->createQuiz(); diff --git a/tests/src/Functional/QuizTestBase.php b/tests/src/Functional/QuizTestBase.php index cb428b1fae3e1ead430c0edaf18295cac70d85b7..3afd36ea5dea84bfb763a8252d644947bab69c69 100644 --- a/tests/src/Functional/QuizTestBase.php +++ b/tests/src/Functional/QuizTestBase.php @@ -114,7 +114,7 @@ abstract class QuizTestBase extends BrowserTestBase { * @return \Drupal\quiz\Entity\Quiz * The newly created Quiz object. */ - public function createQuiz($settings = []) { + public function createQuiz($settings = []): Quiz { $settings += [ 'title' => 'Quiz', 'body' => 'Quiz description', @@ -136,7 +136,7 @@ abstract class QuizTestBase extends BrowserTestBase { * @return \Drupal\quiz\Entity\QuizQuestion * The newly created Quiz Question object. */ - public function createQuestion($settings = []) { + public function createQuestion(array $settings = []): QuizQuestion { $question = QuizQuestion::create($settings); $question->save(); return $question;