harishdurga / laravel-quiz
提供测验功能
Requires
- php: >=8.2.0
- illuminate/support: ^11.0
Requires (Dev)
- nunomaduro/larastan: ^2.0
- orchestra/testbench: ^9.0
- phpunit/phpunit: ^11.0
- dev-main
- v2.0.0
- v1.2.3
- v1.2.2
- v1.2.1
- v1.2.0
- v1.1.12
- v1.1.11
- v1.1.10
- v1.1.9
- v1.1.8
- v1.1.7
- v1.1.6
- v1.1.5
- v1.1.4
- v1.1.3
- v1.1.3-beta
- v1.1.2
- v1.1.1
- v1.1
- v1.0
- dev-support_laravel_11
- dev-support_laravel_10
- dev-38-topicable-namespace
- dev-30-adding-created-by-information-to-different-models
- dev-debug_quizattempt
This package is auto-updated.
Last update: 2024-09-17 16:09:42 UTC
README
Laravel Quiz
使用此包,您可以轻松将测验功能集成到您的Laravel项目中。
特性
- 将主题添加到问题、测验和其他主题
- 支持的题型:单选、多选和填空题
- 添加您自己的题型并定义处理它们的自定义方法
- 灵活的负分设置
- 灵活的测验,具有大多数有用设置(例如:总分、及格分、负分、时长、有效日期、描述等)
- 您的应用程序的任何类型用户都可以成为测验的参与者
- 您的应用程序的任何类型用户,以及任何数量的用户都可以成为测验的作者(不同角色)
- 生成随机测验(进行中)
安装
您可以通过Composer安装此包
composer require harishdurga/laravel-quiz
- Laravel版本:9.X
- PHP版本:8.X
用法
类图
发布供应商文件(配置、迁移、生成器)
php artisan vendor:publish --provider="Harishdurga\LaravelQuiz\LaravelQuizServiceProvider"
如果您正在更新包,您可能需要运行上述命令以发布供应商文件。但请备份配置文件。此外,运行迁移命令以向现有表添加新列。
创建主题
$computer_science = Topic::create([ 'name' => 'Computer Science', 'slug' => 'computer-science', ]);
创建子主题
$algorithms = Topic::create([ 'name' => 'Algorithms', 'slug' => 'algorithms' ]); $computer_science->children()->save($algorithms);
题型
将一个名为 QuestionTypeSeeder
的生成器类发布到 database/seeders
文件夹。运行以下命令以生成题型。
php artisan db:seed --class=\\Harishdurga\\LaravelQuiz\\Database\\Seeders\\QuestionTypeSeeder
当前,此包配置为仅处理以下类型的题目
multiple_choice_single_answer
multiple_choice_multiple_answer
fill_the_blank
创建题型
QuestionType::create(['name'=>'select_all']);
为每种题型定义用户自定义方法以评估答案
尽管此包提供了三种题型,您可以轻松更改用于评估答案的方法。您可以通过更新配置文件中的 get_score_for_question_type
属性来实现这一点。
'get_score_for_question_type' => [ 1 => '\Harishdurga\LaravelQuiz\Models\QuizAttempt::get_score_for_type_1_question', 2 => '\Harishdurga\LaravelQuiz\Models\QuizAttempt::get_score_for_type_2_question', 3 => '\Harishdurga\LaravelQuiz\Models\QuizAttempt::get_score_for_type_3_question', 4 => 'Your custom method' ]
但您的方法需要以下签名
/** * @param QuizAttemptAnswer[] $quizQuestionAnswers All the answers of the quiz question */ public static function get_score_for_type_3_question(QuizAttempt $quizAttempt, QuizQuestion $quizQuestion, array $quizQuestionAnswers, $data = null): float { // Your logic here }
如果您需要向方法传递任何数据,则可以将它作为最后一个 $data
参数传递。当您调用 QuizAttempt
的 calculate_score()
方法时,您可以传递数据作为参数。
创建问题
$question_one = Question::create([ 'name' => 'What is an algorithm?', 'question_type_id' => 1, 'is_active' => true, 'media_url' => 'url', 'media_type' => 'image' ]);
获取某个题型的题目
$question_type->questions
仅获取带选项的问题(有效问题)
Question::hasOptions()->get()
将主题附加到问题
$question->topics()->attach([$computer_science->id, $algorithms->id]);
问题选项
$question_two_option_one = QuestionOption::create([ 'question_id' => $question_two->id, 'name' => 'array', 'is_correct' => true, 'media_type'=>'image', 'media_url'=>'media url' ]);
获取问题的选项
$question->options
创建测验
$quiz = Quiz::create([ 'name' => 'Computer Science Quiz', 'description' => 'Test your knowledge of computer science', 'slug' => 'computer-science-quiz', 'time_between_attempts' => 0, //Time in seconds between each attempt 'total_marks' => 10, 'pass_marks' => 6, 'max_attempts' => 1, 'is_published' => 1, 'valid_from' => now(), 'valid_upto' => now()->addDay(5), 'media_url'=>'', 'media_type'=>'', 'negative_marking_settings'=>[ 'enable_negative_marks' => true, 'negative_marking_type' => 'fixed', 'negative_mark_value' => 0, ] ]);
将主题附加到测验
$quiz->topics()->attach([$topic_one->id, $topic_two->id]);
Topicable
主题可以附加到测验或问题。问题可以存在于测验上下文之外。例如,您可以创建一个问题库,您可以基于附加的主题进行筛选。
负分设置
默认情况下,为了向后兼容,负分标记已启用。您可以通过将 enable_negative_marks
设置为 false 来禁用它。支持两种负分标记类型(negative_marking_type
):fixed
和 percentage
。在问题级别定义的负分标记值将优先于在测验级别定义的值。如果您想设置测验级别的负分标记值,请将 negative_mark_value
设置为您想要设置的值。如果您想设置问题级别的负分标记值,请将 QuizQuestion
的 negative_marks
设置为您希望设置的值。不需要给出负数,而是应以正数给出负分或百分比。
将作者添加到测验中
$admin = Author::create( ['name' => "John Doe"] ); $quiz = Quiz::factory()->make()->create([ 'name' => 'Sample Quiz', 'slug' => 'sample-quiz' ]); QuizAuthor::create([ 'quiz_id' => $quiz->id, 'author_id' => $admin->id, 'author_type' => get_class($admin), 'author_role' => 'admin', ]); $quiz->quizAuthors->first()->author; //Original User
将 CanAuthorQuiz
特性添加到您的模型中,然后您可以通过调用 quizzes
关系来获取所有关联的测验。您可以赋予任何作者角色,并根据您的用例实现访问控制列表(ACL)。
将问题添加到测验中
$quiz_question = QuizQuestion::create([ 'quiz_id' => $quiz->id, 'question_id' => $question->id, 'marks' => 3, 'order' => 1, 'negative_marks'=>1, 'is_optional'=>false ]);
获取测验问题
$quiz->questions
尝试测验
$quiz_attempt = QuizAttempt::create([ 'quiz_id' => $quiz->id, 'participant_id' => $participant->id, 'participant_type' => get_class($participant) ]);
获取测验尝试参与者
MorphTo
关系。
$quiz_attempt->participant
回答测验尝试
QuizAttemptAnswer::create( [ 'quiz_attempt_id' => $quiz_attempt->id, 'quiz_question_id' => $quiz_question->id, 'question_option_id' => $question_option->id, ] );
QuizAttemptAnswer
属于 QuizAttempt
、QuizQuestion
和 QuestionOption
。
获取测验尝试分数
$quiz_attempt->calculate_score()
如果没有找到非必答题的答案,将应用负分。
获取问题的正确选项
$question->correct_options
返回一个 QuestionOption
集合。
public function correct_options(): Collection { return $this->options()->where('is_correct', 1)->get(); }
请参考单元测试和功能测试以了解更多信息。
验证测验问题
您可以使用 QuizAttempt
模型的 validate()
方法来获取测验尝试的总分,而不是使用该方法。此方法将返回一个数组,其中 QuizQuestion 模型的 id
作为关联数组返回的键。 示例:
$quizAttempt->validate($quizQuestion->id); //For a particular question
$quizAttempt->validate(); //For all the questions in the quiz attempt
$quizAttempt->validate($quizQuestion->id,$data); //$data can any type
[ 1 => [ 'score' => 10, 'is_correct' => true, 'correct_answer' => ['One','Five','Seven'], 'user_answer' => ['Five','One','Seven'] ], 2 => [ 'score' => 0, 'is_correct' => false, 'correct_answer' => 'Hello There', 'user_answer' => 'Hello World' ] ]
为了能够渲染除包支持的3种问题类型之外的其他类型的问题的答案,已添加了一个新的配置选项。
'render_answers_responses' => [ 1 => '\Harishdurga\LaravelQuiz\Models\QuizAttempt::renderQuestionType1Answers', 2 => '\Harishdurga\LaravelQuiz\Models\QuizAttempt::renderQuestionType2Answers', 3 => '\Harishdurga\LaravelQuiz\Models\QuizAttempt::renderQuestionType3Answers', ]
通过将问题类型ID作为键,您可以将处理问题类型的自定义函数的路径放入其中。此自定义方法将在 validate()
方法内部通过传递配置中定义的自定义方法的参数 QuizQuestion
对象调用。 示例:
public static function renderQuestionType1Answers(QuizQuestion $quizQuestion,QuizAttempt $quizAttempt,mixed $data=null) { /** * @var Question $actualQuestion */ $actualQuestion = $quizQuestion->question; $answers = $quizQuestion->answers->where('quiz_attempt_id', $quizAttempt->id); $questionOptions = $actualQuestion->options; $correctAnswer = $actualQuestion->correct_options()->first()?->option; $givenAnswer = $answers->first()?->question_option_id; foreach ($questionOptions as $questionOption) { if ($questionOption->id == $givenAnswer) { $givenAnswer = $questionOption->option; break; } } return [$correctAnswer, $givenAnswer]; }
如示例所示,您的自定义方法应返回一个包含两个元素的数组,第一个元素是正确答案,第二个元素是问题的用户答案。发送给 validate()
的任何 $data
都将发送到这些自定义方法,以便您可以为渲染答案发送附加数据。
测试
composer test
变更日志
请参阅 CHANGELOG 了解最近更改的信息。
贡献
请参阅 CONTRIBUTING 了解详细信息。
安全
如果您发现任何安全相关的问题,请通过电子邮件 durgaharish5@gmail.com 反馈,而不是使用问题跟踪器。
致谢
许可证
MIT 许可证(MIT)。有关更多信息,请参阅 许可证文件。
Laravel 包模板
此包是使用 Laravel 包模板 生成的。