Skip to content

Commit

Permalink
Add select to treat all curly/straight punctuation marks as interchan…
Browse files Browse the repository at this point in the history
…geable (default=on)
  • Loading branch information
hieuvu authored and AnupamaSarjoshi committed Jan 20, 2025
1 parent c95736c commit 6cff62a
Show file tree
Hide file tree
Showing 18 changed files with 147 additions and 10 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:

services:
postgres:
image: postgres:13
image: postgres:14
env:
POSTGRES_USER: 'postgres'
POSTGRES_HOST_AUTH_METHOD: 'trust'
Expand Down
3 changes: 2 additions & 1 deletion backup/moodle2/backup_qtype_crossword_plugin.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ protected function define_question_plugin_structure(): backup_plugin_element {
// Now create the qtype own structures.
// phpcs:disable NormalizedArrays.Arrays.CommaAfterLast.MissingMultiLine
$crossword = new backup_nested_element('crossword', ['id'], ['correctfeedback',
'correctfeedbackformat', 'numrows', 'numcolumns', 'accentgradingtype', 'accentpenalty',
'correctfeedbackformat', 'numrows', 'numcolumns', 'accentgradingtype', 'accentpenalty', 'quotematching',
'partiallycorrectfeedback', 'partiallycorrectfeedbackformat',
'incorrectfeedback', 'incorrectfeedbackformat', 'shownumcorrect']);
// phpcs:enable
Expand All @@ -60,6 +60,7 @@ protected function define_question_plugin_structure(): backup_plugin_element {
return $plugin;
}

#[\Override]
public static function get_qtype_fileareas() {
return [
'clue' => 'qtype_crossword_words',
Expand Down
1 change: 1 addition & 0 deletions classes/privacy/provider.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.

/**
* Privacy Subsystem implementation for qtype_crossword.
*
Expand Down
2 changes: 1 addition & 1 deletion classes/util.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public static function safe_normalize(string $string, int $normalizeform = Norma
/**
* Remove the work-break characters '-' and ' ' from an answer.
*
* @param string Full answer.
* @param string $text Full answer.
* @return string Answer with just the letters remaining.
*/
public static function remove_break_characters(string $text): string {
Expand Down
3 changes: 2 additions & 1 deletion db/install.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
<XMLDB PATH="question/type/crossword/db" VERSION="20230310" COMMENT="XMLDB file for Moodle question/type/crossword"
<XMLDB PATH="question/type/crossword/db" VERSION="20250113" COMMENT="XMLDB file for Moodle question/type/crossword"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="../../../../lib/xmldb/xmldb.xsd"
>
Expand All @@ -19,6 +19,7 @@
<FIELD NAME="incorrectfeedback" TYPE="text" NOTNULL="true" SEQUENCE="false" COMMENT="Feedback shown for any incorrect response."/>
<FIELD NAME="incorrectfeedbackformat" TYPE="int" LENGTH="2" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
<FIELD NAME="shownumcorrect" TYPE="int" LENGTH="2" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="If true, then when the user gets a multiple-response question partially correct, tell them how many choices they got correct alongside the feedback."/>
<FIELD NAME="quotematching" TYPE="int" LENGTH="2" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="Whether smart and straight quotes are matched strictly or relaxed."/>
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
Expand Down
15 changes: 15 additions & 0 deletions db/upgrade.php
Original file line number Diff line number Diff line change
Expand Up @@ -134,5 +134,20 @@ function xmldb_qtype_crossword_upgrade($oldversion) {
upgrade_plugin_savepoint(true, 2023032901, 'qtype', 'crossword');
}

if ($oldversion < 2025010700) {

// Define field quotematching to be added to qtype_crossword_options.
$table = new xmldb_table('qtype_crossword_options');
$field = new xmldb_field('quotematching', XMLDB_TYPE_INTEGER, '2', null, XMLDB_NOTNULL, null, '0', 'shownumcorrect');

// Conditionally launch add field quotematching.
if (!$dbman->field_exists($table, $field)) {
$dbman->add_field($table, $field);
}

// Crossword savepoint reached.
upgrade_plugin_savepoint(true, 2025010700, 'qtype', 'crossword');
}

return true;
}
13 changes: 13 additions & 0 deletions edit_crossword_form.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ class qtype_crossword_edit_form extends question_edit_form {
/** @var array The grid options. */
protected $gridoptions;

#[\Override]
protected function definition_inner($mform): void {
// Set grid options.
$this->gridoptions = range(3, 30);
Expand Down Expand Up @@ -69,6 +70,7 @@ protected function definition_inner($mform): void {
$this->add_interactive_settings(true, true);
}

#[\Override]
protected function get_per_answer_fields($mform, $label, $gradeoptions,
&$repeatedoptions, &$wordsoptions): array {
$repeated = [];
Expand Down Expand Up @@ -110,6 +112,7 @@ protected function get_per_answer_fields($mform, $label, $gradeoptions,
return $repeated;
}

#[\Override]
protected function add_per_answer_fields(&$mform, $label, $gradeoptions,
$minoptions = QUESTION_NUMANS_START, $addoptions = QUESTION_NUMANS_ADD) {
$mform->addElement('header', 'words',
Expand All @@ -131,6 +134,7 @@ protected function add_per_answer_fields(&$mform, $label, $gradeoptions,
$this->get_more_choices_string(), true);
}

#[\Override]
protected function get_more_choices_string() {
return get_string('addmorewordblanks', 'qtype_crossword');
}
Expand Down Expand Up @@ -189,6 +193,13 @@ protected function add_question_section(MoodleQuickForm $mform): void {
$optionsaccented);
$mform->setDefault('accentgradingtype', $this->get_default_value('accentgradingtype',
qtype_crossword::ACCENT_GRADING_STRICT));

$mform->addElement('select', 'quotematching', get_string('smart_straight_quote_matching', 'qtype_crossword'), [
get_string('smart_straight_quote_matching_relaxed', 'qtype_crossword'),
get_string('smart_straight_quote_matching_strict', 'qtype_crossword'),
]);
$mform->setDefault('quotematching', 0);

$penaltyoptions = question_bank::fraction_options();
// Remove None and 100%.
unset($penaltyoptions['0.0']);
Expand Down Expand Up @@ -234,6 +245,7 @@ protected function add_coordinates_input(MoodleQuickForm $mform): array {
return $repeated;
}

#[\Override]
protected function data_preprocessing($question): stdClass {
$question = parent::data_preprocessing($question);
$question = $this->data_preprocessing_combined_feedback($question, true);
Expand Down Expand Up @@ -313,6 +325,7 @@ protected function data_preprocessing_words(stdClass $question): stdClass {
return $question;
}

#[\Override]
public function validation($data, $files): array {
$errors = parent::validation($data, $files);
$answercount = 0;
Expand Down
5 changes: 4 additions & 1 deletion lang/en/qtype_crossword.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,15 +54,18 @@
$string['preview'] = 'Preview';
$string['privacy:metadata'] = 'The Crossword plugin does not store any personal data.';
$string['refresh'] = 'Refresh preview';
$string['smart_straight_quote_matching'] = 'Smart and straight quote matching';
$string['smart_straight_quote_matching_relaxed'] = 'Relaxed: ` \' and \' are interchangeable (default)';
$string['smart_straight_quote_matching_strict'] = 'Strict: ` \' and \' all different';
$string['startcolumn'] = 'Column index';
$string['startrow'] = 'Row index';
$string['updateform'] = 'Update the form';
$string['wordhdrhelper_help'] = '<p>As the crossword is generated from the word list, you can either generate a single crossword layout for all users, or use the \'Shuffle crossword layout on new attempt\' option to generate a new layout for each new attempt per student (word combinations allowing).</p>
<p>Add your words and clues using the text fields. If you want a specific word fixed on the grid, tick \'Fix word on grid\' and specify its orientation and placement.</p>
<p>Most characters are supported in this question type, from A-Z, 0-9, diacritics and currency symbols etc. Any curly quotation marks or apostrophes will be converted or interpreted as \'straight\' versions for ease of input and auto-marking.</p>
<p>Add more words by selecting the \'Blanks for 3 more words\' button. Any blank words will be removed when the question is saved.</p>';
$string['wordno'] = 'Word {$a}';
$string['wordlabel'] = 'W{$a->number}{$a->orientation}';
$string['wordno'] = 'Word {$a}';
$string['words'] = 'Words';
$string['words_help'] = 'Please set at least one word and its matching clue, and define its direction and start position. Remember that the words are numbered in the grid according to their order in this section.';
$string['wrongadjacentcharacter'] = 'Two or more consecutive new word breaks detected. Please use a maximum of one between individual words. Note that this does not limit the number of new words in the answer itself.';
Expand Down
14 changes: 14 additions & 0 deletions question.php
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@ class qtype_crossword_question extends question_graded_automatically {
/** @var int format of $incorrectfeedback. */
public $incorrectfeedbackformat;

/** @var bool Whether smart and straight quotes are matched strictly or relaxed. */
public $quotematching;

/**
* Answer field name.
*
Expand All @@ -76,6 +79,7 @@ protected function field(int $key): string {
return 'sub' . $key;
}

#[\Override]
public function get_expected_data(): array {
$response = [];
for ($i = 0; $i < count($this->answers); $i++) {
Expand All @@ -84,6 +88,7 @@ public function get_expected_data(): array {
return $response;
}

#[\Override]
public function get_correct_response(): ?array {
$response = [];
foreach ($this->answers as $key => $answer) {
Expand All @@ -92,6 +97,7 @@ public function get_correct_response(): ?array {
return $response;
}

#[\Override]
public function summarise_response(array $response): ?string {
$responsewords = [];
foreach ($this->answers as $key => $answer) {
Expand All @@ -110,23 +116,27 @@ public function summarise_response(array $response): ?string {
return implode('; ', $responsewords);
}

#[\Override]
public function is_complete_response(array $response): bool {
$filteredresponse = $this->remove_blank_words_from_response($response);
return count($this->answers) === count($filteredresponse);
}

#[\Override]
public function is_gradable_response(array $response): bool {
$filteredresponse = $this->remove_blank_words_from_response($response);
return count($filteredresponse) > 0;
}

#[\Override]
public function get_validation_error(array $response): string {
if ($this->is_complete_response($response)) {
return '';
}
return get_string('pleaseananswerallparts', 'qtype_crossword');
}

#[\Override]
public function is_same_response(array $prevresponse, array $newresponse): bool {
foreach ($this->answers as $key => $notused) {
$fieldname = $this->field($key);
Expand All @@ -138,6 +148,7 @@ public function is_same_response(array $prevresponse, array $newresponse): bool
return true;
}

#[\Override]
public function grade_response(array $response): array {
// Retrieve a number of right answers and total answers.
[$numrightparts, $total] = $this->get_num_parts_right($response);
Expand All @@ -150,6 +161,7 @@ public function grade_response(array $response): array {
return [$fraction, question_state::graded_state_for_fraction($fraction)];
}

#[\Override]
public function get_num_parts_right(array $response): array {
$numright = 0;
foreach ($this->answers as $key => $answer) {
Expand Down Expand Up @@ -177,6 +189,7 @@ public function get_num_parts_partial(array $response): int {
return $numpartial;
}

#[\Override]
public function clear_wrong_from_response(array $response): array {
foreach ($this->answers as $key => $answer) {
if (isset($response[$this->field($key)]) && !$this->is_full_fraction($answer, $response[$this->field($key)])) {
Expand Down Expand Up @@ -249,6 +262,7 @@ private function remove_blank_words_from_response(array $response): array {
});
}

#[\Override]
public function check_file_access($qa, $options, $component, $filearea,
$args, $forcedownload) {

Expand Down
Loading

0 comments on commit 6cff62a

Please sign in to comment.