Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/oat-sa/qti-sdk
A QTI (Question & Test Interoperability) Software Development Kit for PHP
https://github.com/oat-sa/qti-sdk
assessment assessment-item assessment-test branching computer-based-assessment ims-qti outcome-processing php preconditions qti qti-20 qti-21 qti-22 qti-sdk qti-specification question-test-interoperability rendering-engine response-processing template-engine test-interoperability
Last synced: 1 day ago
JSON representation
A QTI (Question & Test Interoperability) Software Development Kit for PHP
- Host: GitHub
- URL: https://github.com/oat-sa/qti-sdk
- Owner: oat-sa
- License: gpl-2.0
- Created: 2014-07-11T10:39:04.000Z (over 10 years ago)
- Default Branch: master
- Last Pushed: 2024-12-12T14:22:55.000Z (10 days ago)
- Last Synced: 2024-12-14T18:04:23.582Z (8 days ago)
- Topics: assessment, assessment-item, assessment-test, branching, computer-based-assessment, ims-qti, outcome-processing, php, preconditions, qti, qti-20, qti-21, qti-22, qti-sdk, qti-specification, question-test-interoperability, rendering-engine, response-processing, template-engine, test-interoperability
- Language: PHP
- Homepage: http://www.taotesting.com
- Size: 16 MB
- Stars: 82
- Watchers: 50
- Forks: 32
- Open Issues: 10
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
[![Latest Version](https://img.shields.io/github/tag/oat-sa/qti-sdk.svg?style=flat&label=release)](https://github.com/oat-sa/qti-sdk/tags)
[![Coverage Status](https://codecov.io/gh/oat-sa/qti-sdk/branch/master/graph/badge.svg?token=Z02IN6NSmp)](https://codecov.io/gh/oat-sa/qti-sdk)
[![License GPL2](http://img.shields.io/badge/licence-gpl2-blue.svg)](http://www.gnu.org/licenses/gpl-2.0.html)
[![Packagist Downloads](http://img.shields.io/packagist/dt/qtism/qtism.svg)](https://packagist.org/packages/qtism/qtism)# QTI Software Development Kit for PHP
An IMS QTI (Question & Test Interoperability) Software Development Kit for PHP 7.0 and higher supporting a wide
range of features described by the [IMS QTI specification family](http://www.imsglobal.org/question).__This implementation of QTI is under constant enhancement. The API of the master branch might change at any time.__
## Features
* Targets QTI 2.0, 2.1 and partially 2.2
* Complete QTI Information Model
* Complete QTI Rule Engine Support
* Custom Operator Hooks through PSR-0/PSR-4
* [Wilbert Kraan's](http://blogs.cetis.ac.uk/wilbert/2013/11/06/using-standards-to-make-assessment-in-e-textbooks-scalable-engaging-but-robust) / [Steve Lay's](http://swl10.blogspot.co.uk/2013/09/transforming-qti-v2-into-xhtml-5.html) Goldilocks Rendering
* CSS Parser for direct QTI Information Model mapping at rendering time
* Item and Test Sessions (with lightning fast binary persistence)
* Nice and Clean API for QTI Document manipulation/traversal
* PreConditions & Branching
* Selection and Ordering
* Response, Outcome and Template Processing
* aria-* attributes
* Unit test driven## Installation (developers)
1. Clone the repository.
2. Make sure you know how [Composer](https://getcomposer.org/download/) works and it is installed on your system.
3. php composer.phar install
4. You are ready!## Unit Tests (developers)
Run Unit Tests by invoking the following shell command:
```shell
cp phpunit.xml.dist phpunit.xml
./vendor/bin/phpunit test
```## Contribute
We are always looking for people to feed the project with:
* Bug reports
* Unit tests
* New features[Please make yourself known](https://github.com/bugalot)!
## QTI Item Session Management
### Introduction Example
The following example demonstrates how to instantiate an item session for a given QTI XML item document. The item
in use in this example is the [*"Composition of Water"*](http://www.imsglobal.org/question/qtiv2p1/examples/items/choice_multiple.xml) item, from the [QTI 2.1 Implementation Guide](http://www.imsglobal.org/question/qtiv2p1/imsqti_implv2p1.html).```php
load('choice_multiple.xml');/*
* A QTI XML document can be used to load various pieces of QTI content such as assessmentItem,
* assessmentTest, responseProcessing, ... components. Our target is an assessmentItem, which is the
* root component of our document.
*/
$item = $itemDoc->getDocumentComponent();/*
* The item session represents the collected and computed data related to the interactions a
* candidate performs on a single assessmentItem. As per the QTI specification, "an item session
* is the accumulation of all attempts at a particular instance of an assessmentItem made by
* a candidate.
*/
$itemSession = new AssessmentItemSession($item);// The candidate is entering the item session, and is beginning his first attempt.
$itemSession->beginItemSession();
$itemSession->beginAttempt();/*
* We instantiate the responses provided by the candidate for this assessmentItem, for the current
* item session. For this assessmentItem, the data collected from the candidate is represented by
* a State, composed of a single ResponseVariable named 'RESPONSE'.
*/
$responses = new State(
array(
// The 'RESPONSE' ResponseVariable has a QTI multiple cardinality, and a QTI identifier baseType.
new ResponseVariable(
'RESPONSE',
Cardinality::MULTIPLE,
BaseType::IDENTIFIER,
/*
* The ResponseVariable value is a Container with multiple cardinality and an identifier
* baseType to meet the cardinality and baseType requirements of the ResponseVariable.
*/
new MultipleContainer(
BaseType::IDENTIFIER,
/*
* The values composing the Container are identifiers 'H' and 'O', which represent
* the correct response to this item.
*/
array(
new QtiIdentifier('H'),
new QtiIdentifier('O')
)
)
)
)
);/*
* The candidate is finishing the current attempt, by providing a correct response.
* ResponseProcessing takes place to produce a new value for the 'SCORE' OutcomeVariable.
*/
$itemSession->endAttempt($responses);// The item session variables and their values can be accessed by their identifier.
echo 'numAttempts: ' . $itemSession['numAttempts'] . "\n";
echo 'completionStatus: ' . $itemSession['completionStatus'] . "\n";
echo 'RESPONSE: ' . $itemSession['RESPONSE'] . "\n";
echo 'SCORE: ' . $itemSession['SCORE'] . "\n";/*
* numAttempts: 1
* completionStatus: completed
* RESPONSE: ['H'; 'O']
* SCORE: 2
*/// End the current item session.
$itemSession->endItemSession();
```### Multiple Attempts Example
As per the QTI specification, item sessions allow a single attempt to be performed by default. Trying to begin an
attempt that will make the item session exceeding the maximum number of attempts will lead to a PHP exception, as in
the following example.```php
load('choice_multiple.xml');
$item = $itemDoc->getDocumentComponent();$itemSession = new AssessmentItemSession($item);
$itemSession->beginItemSession();// Begin 1st attempt.
$itemSession->beginAttempt();
// End attempt by providing an empty response...
$itemSession->endAttempt(new State());// Begin 2nd attempt, but by default, maximum number of attempts is 1.
try {
$itemSession->beginAttempt();
} catch (AssessmentItemSessionException $e) {
echo $e->getMessage();
// A new attempt for item 'choiceMultiple' is not allowed. The maximum number of attempts (1) is reached.
}
```If multiple attempts are permitted on a given assessmentItem, the `itemSessionControl`'s `maxAttempts` attribute
can be modified to allow multiple or unlimited attempts that can be performed by a candidate.```php
load('choice_multiple.xml');
$item = $itemDoc->getDocumentComponent();
$itemSession = new AssessmentItemSession($item);// Set the maximum number of attempts to 0 (means unlimited).
$itemSessionControl = new ItemSessionControl();
$itemSessionControl->setMaxAttempts(0);
$itemSession->setItemSessionControl($itemSessionControl);// Performing multiple attempts will not lead to a PHP exception anymore, because the maximum number of attemps is unlimited!
$itemSession->beginItemSession();// 1st attempt will be an incorrect response from the candidate (['H'; 'Cl']).
$responses = new State(
array(
new ResponseVariable(
'RESPONSE',
Cardinality::MULTIPLE,
BaseType::IDENTIFIER,
new MultipleContainer(
BaseType::IDENTIFIER,
array(
new QtiIdentifier('H'),
new QtiIdentifier('Cl')
)
)
)
)
);$itemSession->endAttempt($responses);
echo 'numAttempts: ' . $itemSession['numAttempts'] . "\n";
echo 'completionStatus: ' . $itemSession['completionStatus'] . "\n";
echo 'RESPONSE: ' . $itemSession['RESPONSE'] . "\n";
echo 'SCORE: ' . $itemSession['SCORE'] . "\n";/*
* numAttempts: 1
* completionStatus: completed
* RESPONSE: ['H'; 'N']
* SCORE: 0
*/// 2nd attempt will send a correct response this time (['H'; 'O'])!
$itemSession->beginAttempt();
$responses['RESPONSE'][1]->setValue('O');
$itemSession->endAttempt();echo 'numAttempts: ' . $itemSession['numAttempts'] . "\n";
echo 'completionStatus: ' . $itemSession['completionStatus'] . "\n";
echo 'RESPONSE: ' . $itemSession['RESPONSE'] . "\n";
echo 'SCORE: ' . $itemSession['SCORE'] . "\n";/*
* numAttempts: 2
* completionStatus: completed
* RESPONSE: ['H'; 'O']
* SCORE: 2
*/$itemSession->endItemSession();
```You can get more information on the QTI-SDK GitHub Wiki!
## QTI Rendering
The QTI Software Development Kit enables you to transform XML serialized QTI files
into their (X)HTML5 Goldilocks equivalent. The following shell command renders the `path/to/qti.xml` QTI file into an HTML5
document using the (X)HTML5 Golidlocks rendering flavour with indentation formatting. The rendering output (stdout)
is redirected to the `/home/jerome/qti.html` file.```shell
./vendor/bin/qtisdk render -df --source path/to/qti.xml --flavour goldilocks > /home/jerome/qti.html
```For additional help and information, just call the help screen to know about the features provided by the rendering binaries!
```shell
./vendor/bin/qtisdk render --help
```## Configuration
As for other major PHP frameworks such as [Doctrine](http://stackoverflow.com/questions/21925354/doctrine-is-freaking-out-when-i-turn-on-php-opcache-on) QTI-SDK makes use
of annotations. In such a context, the two following Zend Opcache configuration directives must be
configured as below.* [opcache.save_comments](http://php.net/manual/en/opcache.configuration.php#ini.opcache.save-comments): 1