Skip to content

MelisCmsMcqEngine

Data, services, XML snapshots, scoring, and front-office quiz renderer for the MCQ (quiz) system. Package melisplatform/melis-cms-mcq-engine.

Purpose

MelisCmsMcqEngine is the data and service layer of the MCQ system: it owns the database tables, the services for questions, answers, MCQs, groups and categories, the XML snapshot that freezes each assembled test, the random-model question picker, answer scoring / passing-rate evaluation, and the front-office quiz renderer. The back-office UI that drives it is MelisCmsMcq — the engine itself has no screens of its own. Think MelisEngine ↔ MelisCms, but for quizzes.

The assembled test is stored as mcq_xml so rendering and scoring read a self-contained snapshot, not a live join, ensuring the exact MCQ a user assembled is preserved even if underlying questions are later edited.

Enable it

Add to config/melis.module.load.php:

php
return [
    // …
    'MelisCmsMcqEngine',
];

Requires: melisplatform/melis-cms (^5.3), melisplatform/melis-cms-tags (^5.3), laminas/laminas-paginator, PHP ^8.1|^8.3. The module ships dbdeploy: true so its tables are created/updated automatically. Install chain: melis-cms-mcqmelis-cms-mcq-enginemelis-cms + melis-cms-tags.

Key services

All services extend MelisCore's general service and fire *_start / *_end events. Aliases are registered in config/module.config.php.

Service aliasRole
MelisCmsMcqServiceMCQs: save, delete, list, generate/fetch MCQ XML, shuffle order, evaluate answers (scoring).
MelisCmsMcqQuestionsServiceQuestions: CRUD, XML generation, basket, random-model picker.
MelisCmsMcqAnswersServiceAnswers: CRUD, correct-answer check, answer count per question.
MelisCmsMcqGroupsServiceMCQ groups: CRUD, assemble groups+questions for an MCQ, deactivate related MCQs.
MelisCmsMcqQuestionCategoryServiceQuestion categories (table melis_cms_mcq_question_groups): CRUD.

Selected methods

MelisCmsMcqService

MethodRole
getMcq($mcqId)Returns the assembled MCQ XML; shuffles question order if mcq_random_order is set.
generateMcqXml($mcqProperties, $mcqTrans, $groupsData)Builds the full test XML from groups + questions and stores it in mcq_xml.
evaluateAnswers($mcqXml, $userAnswers, $passingPercentage)Scores an MCQ-type submission; skips Open Ended; returns score + pass/fail.
getMcqList / saveMcqItem / deleteMcqByIdStandard list/save/delete.

MelisCmsMcqQuestionsService

MethodRole
generateQuestionXml()Builds the per-question XML snapshot on save.
updateMcqQuestionDataXml()Refreshes the question snapshot inside every MCQ that uses it.
getRandomQuestionIds($difficultyId, $categoryId, $tagId, $numberOfQuestions, $excludedIds)Auto-selects N question IDs by difficulty / category / tag.
generateRandomQuestions($userId, $difficultyId, $categoryId, $tags, $numberOfQuestions, $langId, $alreadySelected)Higher-level random picker with exclusion list.
getQuestionsBasketList / processBasketQuestionsManages the per-user question basket (cart).

Front office

ItemRole
renderMcqQuestions view helper (McqQuestionRendererHelper)Converts mcq_xml to an array and renders the quiz through the chosen template. No MelisTemplatingPlugin — the host template decides placement.
Default templateview/templates/default-preview-template.phtml
McqPreviewTemplatesSelect form-element factoryPopulates a select with templates registered under mcq_preview_templates in app.interface.php.

Additional form-element factories used by the back-office: McqQuestionCategoriesSelect, McqQuestionsDifficultySelect, QuestionsTypesSelect.

Database tables

Naming note. The back-office "Question categories" map to melis_cms_mcq_question_groups (service MelisCmsMcqQuestionCategoryService). The back-office "MCQ groups" map to melis_cms_mcq_groups (service MelisCmsMcqGroupsService). Two distinct "group" tables — do not conflate them.

TableHolds
melis_cms_mcqAn MCQ/test: mcq_status, mcq_code, mcq_random_order, mcq_xml (assembled test snapshot), mcq_passing_rate, dates/users.
melis_cms_mcq_transMCQ name per language (mcqt_name).
melis_cms_mcq_questionsA question: mcqq_status, mcqq_code, mcqq_type, mcqq_group_id, mcqq_difficulty_id, mcqq_xml (question+answers snapshot).
melis_cms_mcq_questions_transQuestion text, mcqqt_candidate_note, mcqqt_corrector_note per language.
melis_cms_mcq_answersAn answer: mcqa_question_id, mcqa_status, mcqa_correct_answer, mcqa_code.
melis_cms_mcq_answers_transAnswer text per language (mcqat_answer_text).
melis_cms_mcq_question_typesQuestion types: 1 = MCQ, 2 = Open Ended.
melis_cms_mcq_questions_difficulty (+_trans)Difficulties: 1 = Easy, 2 = Medium, 3 = Hard.
melis_cms_mcq_question_groups (+_trans)Question categories (mcqqg_id, mcqqg_code, mcqqgt_name).
melis_cms_mcq_groups (+_trans)MCQ groups (mcqg_id, mcqg_mcq_id, mcqg_code, mcqgt_name), tied to a specific MCQ.
melis_cms_mcq_questions_listLinks questions ↔ an MCQ (mcmql_mcq_id, mcmql_question_id).
melis_cms_mcq_groups_listLinks groups within an MCQ (added by migration).
melis_cms_mcq_questions_tags_listQuestion ↔ tag links (MelisCmsTags).
melis_cms_mcq_basketsPer-user question basket (cart).

Example

php
$sm = $this->getServiceLocator();

// --- Fetch and render a quiz ---
$mcqSvc = $sm->get('MelisCmsMcqService');
$mcqXml = $mcqSvc->getMcq($mcqId); // shuffles if mcq_random_order is set

// In a phtml template:
echo $this->renderMcqQuestions(
    'MelisCmsMcqEngine/default-template',
    $mcqXml,
    $langId
);

// --- Score a submission ---
$result = $mcqSvc->evaluateAnswers($mcqXml, $userAnswers, 50);
// $result['global'] => ['score', 'pass', 'total', 'checked', 'skipped']
// $result['details'] => per-question outcome

// --- Random model: auto-select N questions ---
$qSvc = $sm->get('MelisCmsMcqQuestionsService');
$ids  = $qSvc->getRandomQuestionIds(
    $difficultyId,
    $categoryId,
    $tagId,
    $numberOfQuestions,
    $excludedIds
);

Key files

ConcernPath
Module wiring + service aliasesvendor/melisplatform/melis-cms-mcq-engine/config/module.config.php
Plugin config (default groups, preview templates)vendor/melisplatform/melis-cms-mcq-engine/config/app.interface.php
MCQ service (XML, scoring)vendor/melisplatform/melis-cms-mcq-engine/src/Service/MelisCmsMcqService.php
Questions service (basket, random model)vendor/melisplatform/melis-cms-mcq-engine/src/Service/MelisCmsMcqQuestionsService.php
Answers servicevendor/melisplatform/melis-cms-mcq-engine/src/Service/MelisCmsMcqAnswersService.php
Groups servicevendor/melisplatform/melis-cms-mcq-engine/src/Service/MelisCmsMcqGroupsService.php
Question category servicevendor/melisplatform/melis-cms-mcq-engine/src/Service/MelisCmsMcqQuestionCategoryService.php
Table gatewaysvendor/melisplatform/melis-cms-mcq-engine/src/Model/Tables/
Form-element factoriesvendor/melisplatform/melis-cms-mcq-engine/src/Form/Factory/
View helpervendor/melisplatform/melis-cms-mcq-engine/src/View/Helper/McqQuestionRendererHelper.php
Default front templatevendor/melisplatform/melis-cms-mcq-engine/view/templates/default-preview-template.phtml
DB install + migrationsvendor/melisplatform/melis-cms-mcq-engine/install/dbdeploy/

See also: Module reference · MelisCmsMcq · MelisCms