Skip to content

Commit

Permalink
Improve sort of matching type tasks
Browse files Browse the repository at this point in the history
Will order by correct/wrong and group matches on same row
HFP-1250
  • Loading branch information
icc committed Jul 17, 2017
1 parent f1105f4 commit 78233cf
Showing 1 changed file with 138 additions and 36 deletions.
174 changes: 138 additions & 36 deletions type-processors/matching-processor.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,113 @@ function generateRows($mappedCRP, $mappedResponse, $dropzones, $draggables) {
return $html;
}

/**
* Sort handler for comparing result rows
*
* @param stdClass $a
* @param stdClass $b
* @return int
*/
private static function rowcmp($a, $b) {
if ($a->isCorrect && $b->isCorrect || !$a->isCorrect && !$b->isCorrect) {
return strcmp($a->response, $b->response);
}
if ($a->isCorrect && !$b->isCorrect) {
return -1;
}
if (!$a->isCorrect && $b->isCorrect) {
return 1;
}
}

/**
* Creates the inital set of rows needed when generating the table HTML
*
* @param array $draggables
* @param array $crp
* @param array $response
* @return array
*/
private static function createUserAnswerRows(&$draggables, &$crp, &$response) {
// Create list with all rows to display
$rows = array();
foreach ($response as $key => $answer) {

$row = (object) array(
'isCorrect' => in_array($answer, $crp),
'crp' => '',
);

// Locate response label
foreach ($draggables as $draggable) {
if ($draggable->id === $answer) {
$row->response = $draggable->value;
break;
}
}

$rows[] = $row;
}

// Sort rows
usort($rows, array('MatchingProcessor', 'rowcmp'));
return $rows;
}

/**
* Creates a list of soluton labels.
*
* @param array $draggables
* @param array $crp
* @return array
*/
private static function createSolutionRows(&$draggables, &$crp) {
// Create list of solution labels
$solutions = array();
foreach ($crp as $pattern) {
$solutions[] = $draggables[$pattern]->value;
}
sort($solutions);
return $solutions;
}

/**
* Puts the solutions labels into the approperiate rows.
*
* @param array $rows
* @param array $solutions
*/
private static function addSolutionsToRows(&$rows, &$solutions) {
// Add solution labels to rows
foreach ($rows as $key => &$row) {
if (empty($solutions)) {
break; // All solutions have been added
}

if ($row->isCorrect) {
// Add solution if hasn't been added yet
$index = array_search($row->response, $solutions);
if ($index !== FALSE) {
$row->crp = $solutions[$index];
unset($solutions[$index]); // Prevent adding multiple times
}
}
else {
// Add the next solution
$row->crp = array_shift($solutions);
}
}

// In case we still have some solutions left, add extra rows for them
foreach ($solutions as $solution) {
$rows[] = (object) array(
'isCorrect' => FALSE,
'crp' => $solution,
'response' => '',
);
}
}

/**
* Generate row for a single dropzone and populate it with correct answers and
* user answers
Expand All @@ -184,59 +291,54 @@ function generateRows($mappedCRP, $mappedResponse, $dropzones, $draggables) {
* @return string Drop zone rows element
*/
function generateDropzoneRows($dropzone, $draggables, $crp, $response) {
$dzRows = sizeof($crp) > sizeof($response) ? sizeof($crp) : sizeof($response);

// Skip row if no correct or user answers
if ($dzRows <= 0) {
return '';
if (!count($response) && !count($crp)) {
return ''; // Skip if no correct or user answers
}

$rows = '';
// Get rows needed to display user answers
$rows = self::createUserAnswerRows($draggables, $crp, $response);

// Get correct solutions labels for the task
$solutions = self::createSolutionRows($draggables, $crp);

// Merges the solutions into the correct rows
self::addSolutionsToRows($rows, $solutions);

// Ready to generate the HTML
$rowsHtml = '';
$lastCellInRow = 'h5p-matching-last-cell-in-row';
$numRows = count($rows);

for ($i = 0; $i < $dzRows; $i++) {
$row = '';
$tdClass = $i >= $dzRows - 1 ? $lastCellInRow : '';
foreach ($rows as $key => &$row) {
$rowHtml = '';
$tdClass = ($key >= $numRows - 1 ? $lastCellInRow : '');

if ($i === 0) {
// Add drop zone
$row .=
if ($key === 0) {
// Print Drop Zone
$rowHtml .=
'<th class="' . 'h5p-matching-dropzone ' . $lastCellInRow . '"' .
' rowspan="' . $dzRows . '"' .
' rowspan="' . $numRows . '"' .
'>' .
$dropzone->value .
'</th>';
}

// Add correct response pattern
$crpCellContent = isset($crp[$i]) ? $draggables[$crp[$i]]->value : '';
$row .= '<td class="' . $tdClass . '">' .
$crpCellContent .
$rowHtml .= '<td class="' . $tdClass . '">' .
$row->crp .
'</td>';


// Add user response
$isCorrectClass = '';
$responseCellContent = '';
if (isset($response[$i])) {
$isCorrectClass = isset($response[$i]) && in_array($response[$i], $crp) ?
'h5p-matching-draggable-correct' : 'h5p-matching-draggable-wrong';
foreach ($draggables as $draggable) {
if ($draggable->id === $response[$i]) {
$responseCellContent = $draggable->value;
break;
}
}
}

$classes = $tdClass . (sizeof($isCorrectClass) ? ' ' : '') . $isCorrectClass;
$row .= '<td class="' . $classes . '">' .
$responseCellContent .
// Add user reponse
$correctClass = ($row->isCorrect ? 'h5p-matching-draggable-correct' : 'h5p-matching-draggable-wrong');
$classes = $tdClass . ($tdClass !== '' && $correctClass !== '' ? ' ' : '') . ($row->response !== '' ? $correctClass : '');
$rowHtml .= '<td class="' . $classes . '">' .
$row->response .
'</td>';

$rows .= '<tr>' . $row . '</tr>';
$rowsHtml .= '<tr>' . $rowHtml . '</tr>';
}
return $rows;

return $rowsHtml;
}

/**
Expand Down

0 comments on commit 78233cf

Please sign in to comment.