Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
<?php
2
// This file is part of Moodle - http://moodle.org/
3
//
4
// Moodle is free software: you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation, either version 3 of the License, or
7
// (at your option) any later version.
8
//
9
// Moodle is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
// GNU General Public License for more details.
13
//
14
// You should have received a copy of the GNU General Public License
15
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
16
/**
17
 * @package    backup-convert
18
 * @copyright  2011 Darko Miletic <dmiletic@moodlerooms.com>
19
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
20
 */
21
 
22
defined('MOODLE_INTERNAL') or die('Direct access to this script is forbidden.');
23
 
24
require_once('cc_utils.php');
25
require_once('cc_general.php');
26
 
27
abstract class cc_xml_namespace {
28
    const xml = 'http://www.w3.org/XML/1998/namespace';
29
}
30
 
31
abstract class cc_qti_metadata {
32
    // Assessment.
33
    const qmd_assessmenttype       = 'qmd_assessmenttype';
34
    const qmd_scoretype            = 'qmd_scoretype';
35
    const qmd_feedbackpermitted    = 'qmd_feedbackpermitted';
36
    const qmd_hintspermitted       = 'qmd_hintspermitted';
37
    const qmd_solutionspermitted   = 'qmd_solutionspermitted';
38
    const qmd_timelimit            = 'qmd_timelimit';
39
    const cc_allow_late_submission = 'cc_allow_late_submission';
40
    const cc_maxattempts           = 'cc_maxattempts';
41
    const cc_profile               = 'cc_profile';
42
 
43
    // Items.
44
    const cc_weighting         = 'cc_weighting';
45
    const qmd_scoringpermitted = 'qmd_scoringpermitted';
46
    const qmd_computerscored   = 'qmd_computerscored';
47
    const cc_question_category = 'cc_question_category';
48
}
49
 
50
abstract class cc_qti_profiletype {
51
    const multiple_choice   = 'cc.multiple_choice.v0p1';
52
    const multiple_response = 'cc.multiple_response.v0p1';
53
    const true_false        = 'cc.true_false.v0p1';
54
    const field_entry       = 'cc.fib.v0p1';
55
    const pattern_match     = 'cc.pattern_match.v0p1';
56
    const essay             = 'cc.essay.v0p1';
57
 
58
    /**
59
     *
60
     * validates a profile value
61
     * @param string $value
62
     * @return boolean
63
     */
64
    public static function valid($value) {
65
        static $verification_values = array( self::essay,
66
                                             self::field_entry,
67
                                             self::multiple_choice,
68
                                             self::multiple_response,
69
                                             self::pattern_match,
70
                                             self::true_false
71
                                           );
72
        return in_array($value, $verification_values);
73
    }
74
 
75
}
76
 
77
abstract class cc_qti_values {
78
    const exam_profile = 'cc.exam.v0p1';
79
    const Yes          = 'Yes';
80
    const No           = 'No';
81
    const Response     = 'Response';
82
    const Solution     = 'Solution';
83
    const Hint         = 'Hint';
84
    const Examination  = 'Examination';
85
    const Percentage   = 'Percentage';
86
    const unlimited    = 'unlimited';
87
    const Single       = 'Single';
88
    const Multiple     = 'Multiple';
89
    const Ordered      = 'Ordered';
90
    const Asterisk     = 'Asterisk';
91
    const Box          = 'Box';
92
    const Dashline     = 'Dashline';
93
    const Underline    = 'Underline';
94
    const Decimal      = 'Decimal';
95
    const Integer      = 'Integer';
96
    const Scientific   = 'Scientific';
97
    const String       = 'String';
98
    const SCORE        = 'SCORE';
99
    const Set          = 'Set';
100
    const Complete     = 'Complete';
101
    const texttype     = 'text/plain';
102
    const htmltype     = 'text/html';
103
}
104
 
105
abstract class cc_qti_tags {
106
    const questestinterop = 'questestinterop';
107
    const assessment = 'assessment';
108
    const qtimetadata = 'qtimetadata';
109
    const qtimetadatafield = 'qtimetadatafield';
110
    const fieldlabel = 'fieldlabel';
111
    const fieldentry = 'fieldentry';
112
    const section = 'section';
113
    const ident = 'ident';
114
    const item = 'item';
115
    const title = 'title';
116
    const itemmetadata = 'itemmetadata';
117
    const presentation = 'presentation';
118
    const material = 'material';
119
    const mattext = 'mattext';
120
    const matref = 'matref';
121
    const matbreak = 'matbreak';
122
    const texttype = 'texttype';
123
    const response_lid = 'response_lid';
124
    const render_choice = 'render_choice';
125
    const response_label = 'response_label';
126
    const resprocessing = 'resprocessing';
127
    const outcomes = 'outcomes';
128
    const decvar = 'decvar';
129
    const respcondition = 'respcondition';
130
    const conditionvar = 'conditionvar';
131
    const other = 'other';
132
    const displayfeedback = 'displayfeedback';
133
    const maxvalue = 'maxvalue';
134
    const minvalue = 'minvalue';
135
    const varname = 'varname';
136
    const vartype = 'vartype';
137
    const continue_ = 'continue';
138
    const feedbacktype = 'feedbacktype';
139
    const linkrefid = 'linkrefid';
140
    const varequal = 'varequal';
141
    const respident = 'respident';
142
    const itemfeedback = 'itemfeedback';
143
    const flow_mat = 'flow_mat';
144
    const rcardinality = 'rcardinality';
145
    const charset = 'charset';
146
    const label = 'label';
147
    const uri = 'uri';
148
    const width = 'width';
149
    const height = 'height';
150
    const x0 = 'x0';
151
    const y0 = 'y0';
152
    const xml_lang = 'lang';
153
    const xml_space = 'space';
154
    const rubric = 'rubric';
155
    const altmaterial = 'altmaterial';
156
    const presentation_material = 'presentation_material';
157
    const t_class = 'class';
158
    const material_ref = 'material_ref';
159
    const rtiming = 'rtiming';
160
    const render_fib = 'render_fib';
161
    const shuffle = 'shuffle';
162
    const minnumber = 'minnumber';
163
    const maxnumber = 'maxnumber';
164
    const encoding = 'encoding';
165
    const maxchars = 'maxchars';
166
    const prompt = 'prompt';
167
    const fibtype = 'fibtype';
168
    const rows = 'rows';
169
    const columns = 'columns';
170
    const labelrefid = 'labelrefid';
171
    const rshuffle = 'rshuffle';
172
    const match_group = 'match_group';
173
    const match_max = 'match_max';
174
    const flow = 'flow';
175
    const response_str = 'response_str';
176
    const flow_label = 'flow_label';
177
    const setvar = 'setvar';
178
    const action = 'action';
179
    const and_ = 'and';
180
    const not_ = 'not';
181
    const case_ = 'case';
182
    const varsubstring = 'varsubstring';
183
    const hint = 'hint';
184
    const solution = 'solution';
185
    const feedbackstyle = 'feedbackstyle';
186
    const solutionmaterial = 'solutionmaterial';
187
    const hintmaterial = 'hintmaterial';
188
}
189
 
190
class cc_question_metadata_base {
191
    /**
192
     * @var array
193
     */
194
    protected $metadata = array();
195
 
196
    /**
197
     * @param string $setting
198
     * @param mixed $value
199
     */
200
    protected function set_setting($setting, $value = null) {
201
        $this->metadata[$setting] = $value;
202
    }
203
 
204
    /**
205
     * @param string $setting
206
     * @return mixed
207
     */
208
    protected function get_setting($setting) {
209
        $result = null;
210
        if (array_key_exists($setting, $this->metadata)) {
211
            $result = $this->metadata[$setting];
212
        }
213
        return $result;
214
    }
215
 
216
    /**
217
     * @param string $setting
218
     * @param string $namespace
219
     * @param string $value
220
     */
221
    protected function set_setting_wns($setting, $namespace, $value = null) {
222
        $this->metadata[$setting] = array($namespace => $value);
223
    }
224
 
225
    /**
226
     * @param string $setting
227
     * @param boolean $value
228
     */
229
    protected function enable_setting_yesno($setting, $value = true) {
230
        $svalue = $value ? cc_qti_values::Yes : cc_qti_values::No;
231
        $this->set_setting($setting, $svalue);
232
    }
233
 
234
    /**
235
     * @param XMLGenericDocument $doc
236
     * @param DOMNode $item
237
     * @param string $namespace
238
     */
239
    public function generate_attributes(XMLGenericDocument &$doc, DOMNode &$item, $namespace) {
240
        foreach ($this->metadata as $attribute => $value) {
241
            if (!is_null($value)) {
242
                if (!is_array($value)) {
243
                    $doc->append_new_attribute_ns($item, $namespace, $attribute, $value);
244
                } else {
245
                    $ns = key($value);
246
                    $nval = current($value);
247
                    if (!is_null($nval)) {
248
                        $doc->append_new_attribute_ns($item, $ns, $attribute, $nval);
249
                    }
250
                }
251
            }
252
        }
253
    }
254
 
255
    /**
256
     * @param XMLGenericDocument $doc
257
     * @param DOMNode $item
258
     * @param string $namespace
259
     */
260
    public function generate(XMLGenericDocument &$doc, DOMNode &$item, $namespace) {
261
        $qtimetadata = $doc->append_new_element_ns($item, $namespace, cc_qti_tags::qtimetadata);
262
        foreach ($this->metadata as $label => $entry) {
263
            if (!is_null($entry)) {
264
                $qtimetadatafield = $doc->append_new_element_ns($qtimetadata, $namespace, cc_qti_tags::qtimetadatafield);
265
                $doc->append_new_element_ns($qtimetadatafield, $namespace, cc_qti_tags::fieldlabel, $label);
266
                $doc->append_new_element_ns($qtimetadatafield, $namespace, cc_qti_tags::fieldentry, $entry);
267
            }
268
        }
269
    }
270
}
271
 
272
class cc_question_metadata extends cc_question_metadata_base {
273
 
274
    public function set_category($value) {
275
        $this->set_setting(cc_qti_metadata::cc_question_category, $value);
276
    }
277
 
278
    public function set_weighting($value) {
279
        $this->set_setting(cc_qti_metadata::cc_weighting, $value);
280
    }
281
 
282
    public function enable_scoringpermitted($value = true) {
283
        $this->enable_setting_yesno(cc_qti_metadata::qmd_scoringpermitted, $value);
284
    }
285
 
286
    public function enable_computerscored($value = true) {
287
        $this->enable_setting_yesno(cc_qti_metadata::qmd_computerscored, $value);
288
    }
289
 
290
    /**
291
     *
292
     * Constructs metadata
293
     * @param string $profile
294
     * @throws InvalidArgumentException
295
     */
296
    public function __construct($profile) {
297
        if (!cc_qti_profiletype::valid($profile)) {
298
            throw new InvalidArgumentException('Invalid profile type!');
299
        }
300
        $this->set_setting(cc_qti_metadata::cc_profile, $profile);
301
        $this->set_setting(cc_qti_metadata::cc_question_category);
302
        $this->set_setting(cc_qti_metadata::cc_weighting        );
303
        $this->set_setting(cc_qti_metadata::qmd_scoringpermitted);
304
        $this->set_setting(cc_qti_metadata::qmd_computerscored  );
305
    }
306
}
307
 
308
 
309
class cc_assesment_metadata extends cc_question_metadata_base {
310
 
311
    public function enable_hints($value = true) {
312
        $this->enable_setting_yesno(cc_qti_metadata::qmd_hintspermitted, $value);
313
    }
314
 
315
    public function enable_solutions($value = true) {
316
        $this->enable_setting_yesno(cc_qti_metadata::qmd_solutionspermitted, $value);
317
    }
318
 
319
    public function enable_latesubmissions($value = true) {
320
        $this->enable_setting_yesno(cc_qti_metadata::cc_allow_late_submission, $value);
321
    }
322
 
323
    public function enable_feedback($value = true) {
324
        $this->enable_setting_yesno(cc_qti_metadata::qmd_feedbackpermitted, $value);
325
    }
326
 
327
    public function set_timelimit($value) {
328
        $ivalue = (int)$value;
329
        if (($ivalue < 0) || ($ivalue > 527401)) {
330
            throw new OutOfRangeException('Time limit value out of permitted range!');
331
        }
332
 
333
        $this->set_setting(cc_qti_metadata::qmd_timelimit, $value);
334
    }
335
 
336
    public function set_maxattempts($value) {
337
        $valid_values = array(cc_qti_values::Examination, cc_qti_values::unlimited, 1, 2, 3, 4, 5);
338
        if (!in_array($value, $valid_values)) {
339
            throw new OutOfRangeException('Max attempts has invalid value');
340
        }
341
 
342
        $this->set_setting(cc_qti_metadata::cc_maxattempts, $value);
343
    }
344
 
345
    public function __construct() {
346
        //prepared default values
347
        $this->set_setting(cc_qti_metadata::cc_profile        , cc_qti_values::exam_profile);
348
        $this->set_setting(cc_qti_metadata::qmd_assessmenttype, cc_qti_values::Examination );
349
        $this->set_setting(cc_qti_metadata::qmd_scoretype     , cc_qti_values::Percentage  );
350
        //optional empty values
351
        $this->set_setting(cc_qti_metadata::qmd_feedbackpermitted   );
352
        $this->set_setting(cc_qti_metadata::qmd_hintspermitted      );
353
        $this->set_setting(cc_qti_metadata::qmd_solutionspermitted  );
354
        $this->set_setting(cc_qti_metadata::qmd_timelimit           );
355
        $this->set_setting(cc_qti_metadata::cc_allow_late_submission);
356
        $this->set_setting(cc_qti_metadata::cc_maxattempts          );
357
    }
358
 
359
}
360
 
361
class cc_assesment_mattext extends cc_question_metadata_base {
362
    protected $value = null;
363
 
364
    public function __construct($value = null) {
365
        $this->set_setting(cc_qti_tags::texttype, cc_qti_values::texttype);
366
        $this->set_setting(cc_qti_tags::charset);//, 'ascii-us');
367
        $this->set_setting(cc_qti_tags::label);
368
        $this->set_setting(cc_qti_tags::uri);
369
        $this->set_setting(cc_qti_tags::width);
370
        $this->set_setting(cc_qti_tags::height);
371
        $this->set_setting(cc_qti_tags::x0);
372
        $this->set_setting(cc_qti_tags::y0);
373
        $this->set_setting_wns(cc_qti_tags::xml_lang , cc_xml_namespace::xml);
374
        $this->set_setting_wns(cc_qti_tags::xml_space, cc_xml_namespace::xml);//, 'default');
375
        $this->value = $value;
376
    }
377
 
378
    public function set_label($value) {
379
        $this->set_setting(cc_qti_tags::label, $value);
380
    }
381
 
382
    public function set_uri($value) {
383
        $this->set_setting(cc_qti_tags::uri, $value);
384
    }
385
 
386
    public function set_width_height($width = null, $height = null) {
387
        $this->set_setting(cc_qti_tags::width, $width);
388
        $this->set_setting(cc_qti_tags::height, $height);
389
    }
390
 
391
    public function set_coor($x = null, $y = null) {
392
        $this->set_setting(cc_qti_tags::x0, $x);
393
        $this->set_setting(cc_qti_tags::y0, $y);
394
    }
395
 
396
    public function set_lang($lang = null) {
397
        $this->set_setting_wns(cc_qti_tags::xml_lang , cc_xml_namespace::xml, $lang);
398
    }
399
 
400
    public function set_content($content, $type = cc_qti_values::texttype, $charset = null) {
401
        $this->value = $content;
402
        $this->set_setting(cc_qti_tags::texttype, $type);
403
        $this->set_setting(cc_qti_tags::charset, $charset);
404
    }
405
 
406
    public function generate(XMLGenericDocument &$doc, DOMNode &$item, $namespace) {
407
        $mattext = $doc->append_new_element_ns_cdata($item, $namespace, cc_qti_tags::mattext, $this->value);
408
        $this->generate_attributes($doc, $mattext, $namespace);
409
    }
410
}
411
 
412
class cc_assesment_matref {
413
    protected $linkref = null;
414
 
415
    public function __construct($linkref) {
416
        $this->linkref = $linkref;
417
    }
418
 
419
    public function generate(XMLGenericDocument &$doc, DOMNode &$item, $namespace) {
420
        $doc->append_new_element_ns($item, $namespace, cc_qti_tags::matref, $this->linkref);
421
        $doc->append_new_attribute_ns($node, $namespace, cc_qti_tags::linkrefid, $this->linkref);
422
    }
423
}
424
 
425
class cc_assesment_response_matref extends cc_assesment_matref {
426
    public function generate(XMLGenericDocument &$doc, DOMNode &$item, $namespace) {
427
        $node = $doc->append_new_element_ns($item, $namespace, cc_qti_tags::material_ref);
428
        $doc->append_new_attribute_ns($node, $namespace, cc_qti_tags::linkrefid, $this->linkref);
429
    }
430
}
431
 
432
class cc_assesment_matbreak {
433
    public function generate(XMLGenericDocument &$doc, DOMNode &$item, $namespace) {
434
        $doc->append_new_element_ns($item, $namespace, cc_qti_tags::matbreak);
435
    }
436
}
437
 
438
abstract class cc_assesment_material_base extends cc_question_metadata_base {
439
    /**
440
    * @var mixed
441
    */
442
    protected $mattag = null;
443
    protected $tagname   = null;
444
 
445
    protected function set_tag_value($object) {
446
        $this->mattag  = $object;
447
    }
448
 
449
    public function set_mattext(cc_assesment_mattext $object) {
450
        $this->set_tag_value($object);
451
    }
452
 
453
    public function set_matref(cc_assesment_matref $object) {
454
        $this->set_tag_value($object);
455
    }
456
 
457
    public function set_matbreak(cc_assesment_matbreak $object) {
458
        $this->set_tag_value($object);
459
    }
460
 
461
    public function set_lang($value) {
462
        $this->set_setting_wns(cc_qti_tags::xml_lang , cc_xml_namespace::xml, $value);
463
    }
464
 
465
    public function generate(XMLGenericDocument &$doc, DOMNode &$item, $namespace) {
466
        $material = $doc->append_new_element_ns($item, $namespace, $this->tagname);
467
        $this->generate_attributes($doc, $material, $namespace);
468
        if (!empty($this->mattag)) {
469
            $this->mattag->generate($doc, $material, $namespace);
470
        }
471
        return $material;
472
    }
473
}
474
 
475
class cc_assesment_altmaterial extends cc_assesment_material_base {
476
    public function __construct($value = null) {
477
        $this->set_setting_wns(cc_qti_tags::xml_lang , cc_xml_namespace::xml);
478
        $this->tagname = cc_qti_tags::altmaterial;
479
    }
480
}
481
 
482
class cc_assesment_material extends cc_assesment_material_base {
483
 
484
    protected $altmaterial = null;
485
 
486
    public function __construct($value = null) {
487
        $this->set_setting(cc_qti_tags::label);
488
        $this->set_setting_wns(cc_qti_tags::xml_lang , cc_xml_namespace::xml);
489
        $this->tagname = cc_qti_tags::material;
490
    }
491
 
492
    public function set_label($value) {
493
        $this->set_setting(cc_qti_tags::label, $value);
494
    }
495
 
496
    public function set_altmaterial(cc_assesment_altmaterial $object) {
497
        $this->altmaterial = $object;
498
    }
499
 
500
    public function generate(XMLGenericDocument &$doc, DOMNode &$item, $namespace) {
501
        $material = parent::generate($doc, $item, $namespace);
502
        if (!empty($this->altmaterial)) {
503
            $this->altmaterial->generate($doc, $material, $namespace);
504
        }
505
    }
506
}
507
 
508
class cc_assesment_rubric_base extends cc_question_metadata_base {
509
 
510
    protected $material = null;
511
 
512
    public function set_material($object) {
513
        $this->material = $object;
514
    }
515
 
516
    public function generate(XMLGenericDocument &$doc, DOMNode &$item, $namespace) {
517
        $rubric = $doc->append_new_element_ns($item, $namespace, cc_qti_tags::rubric);
518
        if (!empty($this->material)) {
519
            $this->material->generate($doc, $rubric, $namespace);
520
        }
521
    }
522
}
523
 
524
class cc_assesment_presentation_material_base extends cc_question_metadata_base {
525
    protected $flowmats = array();
526
 
527
    public function add_flow_mat($object) {
528
        $this->flowmats[] = $object;
529
    }
530
 
531
    public function generate(XMLGenericDocument &$doc, DOMNode &$item, $namespace) {
532
        $node = $doc->append_new_element_ns($item, $namespace, cc_qti_tags::presentation_material);
533
        if (!empty($this->flowmats)) {
534
            foreach ($this->flowmats as $flow_mat) {
535
                $flow_mat->generate($doc, $node, $namespace);
536
            }
537
        }
538
    }
539
}
540
 
541
class cc_assesment_flow_mat_base extends cc_question_metadata_base {
542
 
543
    protected $mattag = null;
544
 
545
    protected function set_tag_value($object) {
546
        $this->mattag  = $object;
547
    }
548
 
549
    public function set_flow_mat(cc_assesment_flow_mat_base $object) {
550
        $this->set_tag_value($object);
551
    }
552
 
553
    public function set_material(cc_assesment_material $object) {
554
        $this->set_tag_value($object);
555
    }
556
 
557
    public function set_material_ref(cc_assesment_matref $object) {
558
        $this->set_tag_value($object);
559
    }
560
 
561
    public function __construct($value = null) {
562
        $this->set_setting(cc_qti_tags::t_class);
563
    }
564
 
565
    public function set_class($value) {
566
        $this->set_setting(cc_qti_tags::t_class, $value);
567
    }
568
 
569
    public function generate(XMLGenericDocument &$doc, DOMNode &$item, $namespace) {
570
        $node = $doc->append_new_element_ns($item, $namespace, cc_qti_tags::flow_mat);
571
        $this->generate_attributes($doc, $node, $namespace);
572
        if (!empty($this->mattag)) {
573
            $this->mattag->generate($doc, $node, $namespace);
574
        }
575
    }
576
 
577
}
578
 
579
class cc_assesment_section extends cc_question_metadata_base {
580
    /**
581
     * @var array
582
     */
583
    protected $items = array();
584
 
585
    public function __construct() {
586
        $this->set_setting(cc_qti_tags::ident, cc_helpers::uuidgen('I_'));
587
        $this->set_setting(cc_qti_tags::title);
588
        $this->set_setting_wns(cc_qti_tags::xml_lang, cc_xml_namespace::xml);
589
    }
590
 
591
    public function set_ident($value) {
592
        $this->set_setting(cc_qti_tags::ident, $value);
593
    }
594
 
595
    public function set_title($value) {
596
        $this->set_setting(cc_qti_tags::title, $value);
597
    }
598
 
599
    public function set_lang($value) {
600
        $this->set_setting_wns(cc_qti_tags::xml_lang, cc_xml_namespace::xml, $value);
601
    }
602
 
603
    public function add_item(cc_assesment_section_item $object) {
604
        $this->items[] = $object;
605
    }
606
 
607
    public function generate(XMLGenericDocument &$doc, DOMNode &$item, $namespace) {
608
        $node = $doc->append_new_element_ns($item, $namespace, cc_qti_tags::section);
609
        $this->generate_attributes($doc, $node, $namespace);
610
        if (!empty($this->items)) {
611
            foreach ($this->items as $item) {
612
                $item->generate($doc, $node, $namespace);
613
            }
614
        }
615
    }
616
}
617
 
618
class cc_assesment_itemmetadata extends cc_question_metadata_base {
619
    public function add_metadata($object) {
620
        $this->metadata[] = $object;
621
    }
622
 
623
    public function generate(XMLGenericDocument &$doc, DOMNode &$item, $namespace) {
624
        $node = $doc->append_new_element_ns($item, $namespace, cc_qti_tags::itemmetadata);
625
        if (!empty($this->metadata)) {
626
            foreach ($this->metadata as $metaitem) {
627
                $metaitem->generate($doc, $node, $namespace);
628
            }
629
        }
630
    }
631
}
632
 
633
class cc_assesment_decvartype extends cc_question_metadata_base {
634
 
635
    public function __construct() {
636
        $this->set_setting(cc_qti_tags::varname, cc_qti_values::SCORE);
637
        $this->set_setting(cc_qti_tags::vartype, cc_qti_values::Integer);
638
        $this->set_setting(cc_qti_tags::minvalue);
639
        $this->set_setting(cc_qti_tags::maxvalue);
640
    }
641
 
642
    public function set_vartype($value) {
643
        $this->set_setting(cc_qti_tags::vartype, $value);
644
    }
645
 
646
    public function set_limits($min = null, $max = null) {
647
        $this->set_setting(cc_qti_tags::minvalue, $min);
648
        $this->set_setting(cc_qti_tags::maxvalue, $max);
649
    }
650
 
651
    public function generate(XMLGenericDocument &$doc, DOMNode &$item, $namespace) {
652
        $node = $doc->append_new_element_ns($item, $namespace, cc_qti_tags::decvar);
653
        $this->generate_attributes($doc, $node, $namespace);
654
    }
655
}
656
 
657
 
658
class cc_assignment_conditionvar_othertype extends cc_question_metadata_base {
659
    public function generate(XMLGenericDocument &$doc, DOMNode &$item, $namespace) {
660
        $doc->append_new_element_ns($item, $namespace, cc_qti_tags::other);
661
    }
662
}
663
 
664
class cc_assignment_conditionvar_varequaltype extends cc_question_metadata_base {
665
    protected $tagname = null;
666
    protected $answerid = null;
667
 
668
    public function __construct($value = null) {
669
        if (is_null($value)) {
670
            throw new InvalidArgumentException('Must not pass null!');
671
        }
672
        $this->answerid = $value;
673
        $this->set_setting(cc_qti_tags::respident);
674
        $this->set_setting(cc_qti_tags::case_);//, cc_qti_values::No  );
675
        $this->tagname = cc_qti_tags::varequal;
676
    }
677
 
678
    public function set_respident($value) {
679
        $this->set_setting(cc_qti_tags::respident, $value);
680
    }
681
 
682
    public function enable_case($value = true) {
683
        $this->enable_setting_yesno(cc_qti_tags::case_, $value);
684
    }
685
 
686
    public function generate(XMLGenericDocument &$doc, DOMNode &$item, $namespace) {
687
        $node = $doc->append_new_element_ns($item, $namespace, $this->tagname, $this->answerid);
688
        $this->generate_attributes($doc, $node, $namespace);
689
    }
690
}
691
 
692
class cc_assignment_conditionvar_varsubstringtype extends cc_assignment_conditionvar_varequaltype {
693
    public function __construct($value) {
694
        parent::__construct($value);
695
        $this->tagname = cc_qti_tags::varsubstring;
696
    }
697
}
698
 
699
 
700
class cc_assignment_conditionvar_andtype extends cc_question_metadata_base {
701
    protected $nots = array();
702
    protected $varequals = array();
703
 
704
    public function set_not(cc_assignment_conditionvar_varequaltype $object) {
705
        $this->nots[] = $object;
706
    }
707
 
708
    public function set_varequal(cc_assignment_conditionvar_varequaltype $object) {
709
        $this->varequals[] = $object;
710
    }
711
 
712
    public function generate(XMLGenericDocument &$doc, DOMNode &$item, $namespace) {
713
        $node = $doc->append_new_element_ns($item, $namespace, cc_qti_tags::and_);
714
        if (!empty($this->nots)) {
715
            foreach ($this->nots as $notv) {
716
                $not = $doc->append_new_element_ns($node, $namespace, cc_qti_tags::not_);
717
                $notv->generate($doc, $not, $namespace);
718
            }
719
        }
720
 
721
        if (!empty($this->varequals)) {
722
            foreach ($this->varequals as $varequal) {
723
                $varequal->generate($doc, $node, $namespace);
724
            }
725
        }
726
    }
727
}
728
 
729
class cc_assignment_conditionvar extends cc_question_metadata_base {
730
 
731
    /**
732
     * @var cc_assignment_conditionvar_andtype
733
     */
734
    protected $and = null;
735
    /**
736
     * @var cc_assignment_conditionvar_othertype
737
     */
738
    protected $other = null;
739
    /**
740
     * @var array
741
     */
742
    protected $varequal = array();
743
    /**
744
     * @var cc_assignment_conditionvar_varsubstringtype
745
     */
746
    protected $varsubstring = null;
747
 
748
    public function set_and(cc_assignment_conditionvar_andtype $object) {
749
        $this->and = $object;
750
    }
751
 
752
    public function set_other(cc_assignment_conditionvar_othertype $object) {
753
        $this->other = $object;
754
    }
755
 
756
    public function set_varequal(cc_assignment_conditionvar_varequaltype $object) {
757
        $this->varequal[] = $object;
758
    }
759
 
760
    public function set_varsubstring(cc_assignment_conditionvar_varsubstringtype $object) {
761
        $this->varsubstring = $object;
762
    }
763
 
764
    public function generate(XMLGenericDocument &$doc, DOMNode &$item, $namespace) {
765
        $node = $doc->append_new_element_ns($item, $namespace, cc_qti_tags::conditionvar);
766
 
767
        if (!empty($this->and)) {
768
            $this->and->generate($doc, $node, $namespace);
769
        }
770
 
771
        if (!empty($this->other)) {
772
            $this->other->generate($doc, $node, $namespace);
773
        }
774
 
775
        if (!empty($this->varequal)) {
776
            foreach ($this->varequal as $varequal) {
777
                $varequal->generate($doc, $node, $namespace);
778
            }
779
        }
780
 
781
        if (!empty($this->varsubstring)) {
782
            $this->varsubstring->generate($doc, $node, $namespace);
783
        }
784
    }
785
}
786
 
787
class cc_assignment_displayfeedbacktype extends cc_question_metadata_base {
788
    public function __construct() {
789
        $this->set_setting(cc_qti_tags::feedbacktype);
790
        $this->set_setting(cc_qti_tags::linkrefid);
791
    }
792
 
793
    public function set_feedbacktype($value) {
794
        $this->set_setting(cc_qti_tags::feedbacktype, $value);
795
    }
796
 
797
    public function set_linkrefid($value) {
798
        $this->set_setting(cc_qti_tags::linkrefid, $value);
799
    }
800
 
801
    public function generate(XMLGenericDocument &$doc, DOMNode &$item, $namespace) {
802
        $node = $doc->append_new_element_ns($item, $namespace, cc_qti_tags::displayfeedback);
803
        $this->generate_attributes($doc, $node, $namespace);
804
    }
805
}
806
 
807
 
808
class cc_assignment_setvartype extends cc_question_metadata_base {
809
    /**
810
     * @var integer
811
     */
812
    protected $tagvalue = null;
813
 
814
    public function __construct($tagvalue = 100) {
815
        $this->set_setting(cc_qti_tags::varname, cc_qti_values::SCORE);
816
        $this->set_setting(cc_qti_tags::action , cc_qti_values::Set  );
817
        $this->tagvalue = $tagvalue;
818
    }
819
 
820
    public function set_varname($value) {
821
        $this->set_setting(cc_qti_tags::varname, $value);
822
    }
823
 
824
    public function generate(XMLGenericDocument &$doc, DOMNode &$item, $namespace) {
825
        $node = $doc->append_new_element_ns($item, $namespace, cc_qti_tags::setvar, $this->tagvalue);
826
        $this->generate_attributes($doc, $node, $namespace);
827
    }
828
}
829
 
830
class cc_assesment_respconditiontype extends cc_question_metadata_base {
831
    /**
832
     * @var cc_assignment_conditionvar
833
     */
834
    protected $conditionvar = null;
835
    protected $setvar = array();
836
    protected $displayfeedback = array();
837
 
838
    public function __construct() {
839
        $this->set_setting(cc_qti_tags::title);
840
        $this->set_setting(cc_qti_tags::continue_, cc_qti_values::No);
841
    }
842
 
843
    public function set_title($value) {
844
        $this->set_setting(cc_qti_tags::title, $value);
845
    }
846
 
847
    public function enable_continue($value = true) {
848
        $this->enable_setting_yesno(cc_qti_tags::continue_, $value);
849
    }
850
 
851
    public function set_conditionvar(cc_assignment_conditionvar $object) {
852
        $this->conditionvar = $object;
853
    }
854
 
855
    public function add_setvar(cc_assignment_setvartype $object) {
856
        $this->setvar[] = $object;
857
    }
858
 
859
    public function add_displayfeedback(cc_assignment_displayfeedbacktype $object) {
860
        $this->displayfeedback[] = $object;
861
    }
862
 
863
    public function generate(XMLGenericDocument &$doc, DOMNode &$item, $namespace) {
864
        $node = $doc->append_new_element_ns($item, $namespace, cc_qti_tags::respcondition);
865
        $this->generate_attributes($doc, $node, $namespace);
866
 
867
        if (!empty($this->conditionvar)) {
868
            $this->conditionvar->generate($doc, $node, $namespace);
869
        }
870
 
871
        if (!empty($this->setvar)) {
872
            foreach ($this->setvar as $setvar) {
873
                $setvar->generate($doc, $node, $namespace);
874
            }
875
        }
876
 
877
        if (!empty($this->displayfeedback)) {
878
            foreach ($this->displayfeedback as $displayfeedback) {
879
                $displayfeedback->generate($doc, $node, $namespace);
880
            }
881
        }
882
    }
883
}
884
 
885
 
886
class cc_assesment_resprocessingtype extends cc_question_metadata_base {
887
    /**
888
     * @var cc_assesment_decvartype
889
     */
890
    protected $decvar = null;
891
    /**
892
     * @var array
893
     */
894
    protected $respconditions = array();
895
 
896
    public function set_decvar(cc_assesment_decvartype $object) {
897
        $this->decvar = $object;
898
    }
899
 
900
    public function add_respcondition(cc_assesment_respconditiontype $object) {
901
        $this->respconditions[] = $object;
902
    }
903
 
904
    public function generate(XMLGenericDocument &$doc, DOMNode &$item, $namespace) {
905
        $node = $doc->append_new_element_ns($item, $namespace, cc_qti_tags::resprocessing);
906
        $outcomes = $doc->append_new_element_ns($node, $namespace, cc_qti_tags::outcomes);
907
        if (!empty($this->decvar)) {
908
            $this->decvar->generate($doc, $outcomes, $namespace);
909
        }
910
        if (!empty($this->respconditions)) {
911
            foreach ($this->respconditions as $rcond) {
912
                $rcond->generate($doc, $node, $namespace);
913
            }
914
        }
915
    }
916
}
917
 
918
 
919
class cc_assesment_itemfeedback_shintmaterial_base extends cc_question_metadata_base {
920
    /**
921
     * @var string
922
     */
923
    protected $tagname = null;
924
    /**
925
     * @var array
926
     */
927
    protected $flow_mats = array();
928
    /**
929
     * @var array
930
     */
931
    protected $materials = array();
932
 
933
    /**
934
     * @param cc_assesment_flow_mattype $object
935
     */
936
    public function add_flow_mat(cc_assesment_flow_mattype $object) {
937
        $this->flow_mats[] = $object;
938
    }
939
 
940
    /**
941
     * @param cc_assesment_material $object
942
     */
943
    public function add_material(cc_assesment_material $object) {
944
        $this->materials[] = $object;
945
    }
946
 
947
    public function generate(XMLGenericDocument &$doc, DOMNode &$item, $namespace) {
948
        $node = $doc->append_new_element_ns($item, $namespace, $this->tagname);
949
 
950
        if (!empty($this->flow_mats)) {
951
            foreach ($this->flow_mats as $flow_mat) {
952
                $flow_mat->generate($doc, $node, $namespace);
953
            }
954
        }
955
 
956
        if (!empty($this->materials)) {
957
            foreach ($this->materials as $material) {
958
                $material->generate($doc, $node, $namespace);
959
            }
960
        }
961
    }
962
}
963
 
964
class cc_assesment_itemfeedback_hintmaterial extends cc_assesment_itemfeedback_shintmaterial_base {
965
    public function __construct() {
966
        $this->tagname = cc_qti_tags::hint;
967
    }
968
}
969
 
970
class cc_assesment_itemfeedback_solutionmaterial extends cc_assesment_itemfeedback_shintmaterial_base {
971
    public function __construct() {
972
        $this->tagname = cc_qti_tags::solutionmaterial;
973
    }
974
}
975
 
976
class cc_assesment_itemfeedback_shintype_base extends cc_question_metadata_base {
977
    /**
978
     * @var string
979
     */
980
    protected $tagname = null;
981
    /**
982
     * @var array
983
    */
984
    protected $items = array();
985
 
986
    public function __construct() {
987
        $this->set_setting(cc_qti_tags::feedbackstyle, cc_qti_values::Complete);
988
    }
989
 
990
    public function generate(XMLGenericDocument &$doc, DOMNode &$item, $namespace) {
991
        $node = $doc->append_new_element_ns($item, $namespace, $this->tagname);
992
        $this->generate_attributes($doc, $node, $namespace);
993
 
994
        if (!empty($this->items)) {
995
            foreach ($this->items as $telement) {
996
                $telement->generate($doc, $node, $namespace);
997
            }
998
        }
999
    }
1000
}
1001
 
1002
class cc_assesment_itemfeedback_solutiontype extends cc_assesment_itemfeedback_shintype_base {
1003
    public function __construct() {
1004
        parent::__construct();
1005
        $this->tagname = cc_qti_tags::solution;
1006
    }
1007
 
1008
    /**
1009
     * @param cc_assesment_itemfeedback_solutionmaterial $object
1010
     */
1011
    public function add_solutionmaterial(cc_assesment_itemfeedback_solutionmaterial $object) {
1012
        $this->items[] = $object;
1013
    }
1014
}
1015
 
1016
class cc_assesment_itemfeedbac_hinttype extends cc_assesment_itemfeedback_shintype_base {
1017
    public function __construct() {
1018
        parent::__construct();
1019
        $this->tagname = cc_qti_tags::hint;
1020
    }
1021
 
1022
    /**
1023
     * @param cc_assesment_itemfeedback_hintmaterial $object
1024
     */
1025
    public function add_hintmaterial(cc_assesment_itemfeedback_hintmaterial $object) {
1026
        $this->items[] = $object;
1027
    }
1028
}
1029
 
1030
class cc_assesment_itemfeedbacktype extends cc_question_metadata_base {
1031
    /**
1032
     * @var cc_assesment_flow_mattype
1033
     */
1034
    protected $flow_mat = null;
1035
    /**
1036
     * @var cc_assesment_material
1037
     */
1038
    protected $material = null;
1039
    /**
1040
     * @var cc_assesment_itemfeedback_solutiontype
1041
     */
1042
    protected $solution = null;
1043
    protected $hint = null;
1044
 
1045
    /** @var cc_assignment_displayfeedbacktype item feedback. */
1046
    protected $itemfeedback;
1047
 
1048
    public function __construct() {
1049
        $this->set_setting(cc_qti_tags::ident, cc_helpers::uuidgen('I_'));
1050
        $this->set_setting(cc_qti_tags::title);
1051
    }
1052
 
1053
    /**
1054
     * @param string $value
1055
     */
1056
    public function set_ident($value) {
1057
        $this->set_setting(cc_qti_tags::ident, $value);
1058
    }
1059
 
1060
    /**
1061
     * @param string $value
1062
     */
1063
    public function set_title($value) {
1064
        $this->set_setting(cc_qti_tags::title, $value);
1065
    }
1066
 
1067
    /**
1068
     * @param cc_assesment_flow_mattype $object
1069
     */
1070
    public function set_flow_mat(cc_assesment_flow_mattype $object) {
1071
        $this->flow_mat = $object;
1072
    }
1073
 
1074
    /**
1075
     * @param cc_assesment_material $object
1076
     */
1077
    public function set_material(cc_assesment_material $object) {
1078
        $this->material = $object;
1079
    }
1080
 
1081
    /**
1082
     * @param cc_assesment_itemfeedback_solutiontype $object
1083
     */
1084
    public function set_solution(cc_assesment_itemfeedback_solutiontype $object) {
1085
        $this->solution = $object;
1086
    }
1087
 
1088
    public function set_hint($object) {
1089
        $this->hint = $object;
1090
    }
1091
 
1092
    public function generate(XMLGenericDocument &$doc, DOMNode &$item, $namespace) {
1093
        $node = $doc->append_new_element_ns($item, $namespace, cc_qti_tags::itemfeedback);
1094
        $this->generate_attributes($doc, $node, $namespace);
1095
 
1096
        if (!empty($this->flow_mat) && empty($this->material)) {
1097
            $this->flow_mat->generate($doc, $node, $namespace);
1098
        }
1099
 
1100
        if (!empty($this->material) && empty($this->flow_mat)) {
1101
            $this->material->generate($doc, $node, $namespace);
1102
        }
1103
 
1104
        if (!empty($this->solution)) {
1105
            $this->solution->generate($doc, $node, $namespace);
1106
        }
1107
 
1108
        if (!empty($this->itemfeedback)) {
1109
            $this->itemfeedback->generate($doc, $node, $namespace);
1110
        }
1111
    }
1112
}
1113
 
1114
class cc_assesment_section_item extends cc_assesment_section {
1115
 
1116
    /**
1117
     * @var cc_assesment_itemmetadata
1118
     */
1119
    protected $itemmetadata = null;
1120
    /**
1121
     * @var cc_assesment_presentation
1122
     */
1123
    protected $presentation = null;
1124
    protected $resprocessing = array();
1125
    protected $itemfeedback = array();
1126
 
1127
    public function set_itemmetadata(cc_assesment_itemmetadata $object) {
1128
        $this->itemmetadata = $object;
1129
    }
1130
 
1131
    public function set_presentation(cc_assesment_presentation $object) {
1132
        $this->presentation = $object;
1133
    }
1134
 
1135
    public function add_resprocessing(cc_assesment_resprocessingtype $object) {
1136
        $this->resprocessing[] = $object;
1137
    }
1138
 
1139
    public function add_itemfeedback(cc_assesment_itemfeedbacktype $object) {
1140
        $this->itemfeedback[] = $object;
1141
    }
1142
 
1143
    public function generate(XMLGenericDocument &$doc, DOMNode &$item, $namespace) {
1144
        $node = $doc->append_new_element_ns($item, $namespace, cc_qti_tags::item);
1145
        $this->generate_attributes($doc, $node, $namespace);
1146
 
1147
        if (!empty($this->itemmetadata)) {
1148
            $this->itemmetadata->generate($doc, $node, $namespace);
1149
        }
1150
 
1151
        if (!empty($this->presentation)) {
1152
            $this->presentation->generate($doc, $node, $namespace);
1153
        }
1154
 
1155
        if (!empty($this->resprocessing)) {
1156
            foreach ($this->resprocessing as $resprocessing) {
1157
                $resprocessing->generate($doc, $node, $namespace);
1158
            }
1159
        }
1160
 
1161
        if (!empty($this->itemfeedback)) {
1162
            foreach ($this->itemfeedback as $itemfeedback) {
1163
                $itemfeedback->generate($doc, $node, $namespace);
1164
            }
1165
        }
1166
    }
1167
}
1168
 
1169
class cc_assesment_render_choicetype extends cc_question_metadata_base {
1170
    /**
1171
     * @var array
1172
     */
1173
    protected $materials = array();
1174
 
1175
    /**
1176
     * @var array
1177
     */
1178
    protected $material_refs = array();
1179
 
1180
    /**
1181
     * @var array
1182
     */
1183
    protected $response_labels = array();
1184
    /**
1185
     * @var array
1186
     */
1187
    protected $flow_labels = array();
1188
 
1189
    public function __construct() {
1190
        $this->set_setting(cc_qti_tags::shuffle, cc_qti_values::No);
1191
        $this->set_setting(cc_qti_tags::minnumber);
1192
        $this->set_setting(cc_qti_tags::maxnumber);
1193
    }
1194
 
1195
    public function add_material(cc_assesment_material $object) {
1196
        $this->materials[] = $object;
1197
    }
1198
 
1199
    public function add_material_ref(cc_assesment_response_matref $object) {
1200
        $this->material_refs[] = $object;
1201
    }
1202
 
1203
    public function add_response_label(cc_assesment_response_labeltype $object) {
1204
        $this->response_labels[] = $object;
1205
    }
1206
 
1207
    public function add_flow_label($object) {
1208
        $this->flow_labels[] = $object;
1209
    }
1210
 
1211
    public function enable_shuffle($value = true) {
1212
        $this->enable_setting_yesno(cc_qti_tags::shuffle, $value);
1213
    }
1214
 
1215
    public function set_limits($min = null, $max = null) {
1216
        $this->set_setting(cc_qti_tags::minnumber, $min);
1217
        $this->set_setting(cc_qti_tags::maxnumber, $max);
1218
    }
1219
 
1220
    public function generate(XMLGenericDocument &$doc, DOMNode &$item, $namespace) {
1221
        $node = $doc->append_new_element_ns($item, $namespace, cc_qti_tags::render_choice);
1222
        $this->generate_attributes($doc, $node, $namespace);
1223
 
1224
        if (!empty($this->materials)) {
1225
            foreach ($this->materials as $mattag) {
1226
                $mattag->generate($doc, $node, $namespace);
1227
            }
1228
        }
1229
 
1230
        if (!empty($this->material_refs)) {
1231
            foreach ($this->material_refs as $matreftag) {
1232
                $matreftag->generate($doc, $node, $namespace);
1233
            }
1234
        }
1235
 
1236
        if (!empty($this->response_labels)) {
1237
            foreach ($this->response_labels as $resplabtag) {
1238
                $resplabtag->generate($doc, $node, $namespace);
1239
            }
1240
        }
1241
 
1242
        if (!empty($this->flow_labels)) {
1243
            foreach ($this->flow_labels as $flowlabtag) {
1244
                $flowlabtag->generate($doc, $node, $namespace);
1245
            }
1246
        }
1247
    }
1248
 
1249
}
1250
 
1251
class cc_assesment_flow_mattype extends cc_question_metadata_base {
1252
 
1253
    /**
1254
     * @var cc_assesment_material
1255
     */
1256
    protected $material = null;
1257
    /**
1258
     * @var cc_assesment_response_matref
1259
     */
1260
    protected $material_ref = null;
1261
    /**
1262
     * @var cc_assesment_flow_mattype
1263
     */
1264
    protected $flow_mat = null;
1265
 
1266
    public function __construct() {
1267
        $this->set_setting(cc_qti_tags::t_class);
1268
    }
1269
 
1270
    public function set_class($value) {
1271
        $this->set_setting(cc_qti_tags::t_class, $value);
1272
    }
1273
 
1274
    public function set_material(cc_assesment_material $object) {
1275
        $this->material = $object;
1276
    }
1277
 
1278
    public function set_material_ref(cc_assesment_response_matref $object) {
1279
        $this->material_ref = $object;
1280
    }
1281
 
1282
    public function set_flow_mat(cc_assesment_flow_mattype $object) {
1283
        $this->flow_mat = $object;
1284
    }
1285
 
1286
    public function generate(XMLGenericDocument &$doc, DOMNode &$item, $namespace) {
1287
        $node = $doc->append_new_element_ns($item, $namespace, cc_qti_tags::flow_mat);
1288
        $this->generate_attributes($doc, $node, $namespace);
1289
 
1290
        if (!empty($this->flow_mat)) {
1291
            $this->flow_mat->generate($doc, $node, $namespace);
1292
        }
1293
 
1294
        if (!empty($this->material)) {
1295
            $this->material->generate($doc, $node, $namespace);
1296
        }
1297
 
1298
        if (!empty($this->material_ref)) {
1299
            $this->material_ref->generate($doc, $node, $namespace);
1300
        }
1301
    }
1302
}
1303
 
1304
class cc_assesment_response_labeltype extends cc_question_metadata_base {
1305
    /**
1306
     * @var cc_assesment_material
1307
     */
1308
    protected $material = null;
1309
 
1310
    /**
1311
     * @var cc_assesment_response_matref
1312
     */
1313
    protected $material_ref = null;
1314
 
1315
    /**
1316
     * @var cc_assesment_flow_mattype
1317
     */
1318
    protected $flow_mat = null;
1319
 
1320
    public function __construct() {
1321
        $this->set_setting(cc_qti_tags::ident, cc_helpers::uuidgen('I_'));
1322
        $this->set_setting(cc_qti_tags::labelrefid);
1323
        $this->set_setting(cc_qti_tags::rshuffle);
1324
        $this->set_setting(cc_qti_tags::match_group);
1325
        $this->set_setting(cc_qti_tags::match_max);
1326
    }
1327
 
1328
    public function set_ident($value) {
1329
        $this->set_setting(cc_qti_tags::ident, $value);
1330
    }
1331
 
1332
    public function get_ident() {
1333
        return $this->get_setting(cc_qti_tags::ident);
1334
    }
1335
 
1336
    public function set_labelrefid($value) {
1337
        $this->set_setting(cc_qti_tags::labelrefid, $value);
1338
    }
1339
 
1340
    public function enable_rshuffle($value = true) {
1341
        $this->enable_setting_yesno(cc_qti_tags::rshuffle, $value);
1342
    }
1343
 
1344
    public function set_match_group($value) {
1345
        $this->set_setting(cc_qti_tags::match_group, $value);
1346
    }
1347
 
1348
    public function set_match_max($value) {
1349
        $this->set_setting(cc_qti_tags::match_max, $value);
1350
    }
1351
 
1352
    public function set_material(cc_assesment_material $object) {
1353
        $this->material = $object;
1354
    }
1355
 
1356
    public function set_material_ref(cc_assesment_response_matref $object) {
1357
        $this->material_ref = $object;
1358
    }
1359
 
1360
    public function set_flow_mat(cc_assesment_flow_mattype $object) {
1361
        $this->flow_mat = $object;
1362
    }
1363
 
1364
    public function generate(XMLGenericDocument &$doc, DOMNode &$item, $namespace) {
1365
        $node = $doc->append_new_element_ns($item, $namespace, cc_qti_tags::response_label);
1366
        $this->generate_attributes($doc, $node, $namespace);
1367
 
1368
        if (!empty($this->material)) {
1369
            $this->material->generate($doc, $node, $namespace);
1370
        }
1371
 
1372
        if (!empty($this->material_ref)) {
1373
            $this->material_ref->generate($doc, $node, $namespace);
1374
        }
1375
 
1376
        if (!empty($this->flow_mat)) {
1377
            $this->flow_mat->generate($doc, $node, $namespace);
1378
        }
1379
    }
1380
}
1381
 
1382
class cc_assesment_flow_labeltype extends cc_question_metadata_base {
1383
    /**
1384
     * @var cc_assesment_flow_labeltype
1385
     */
1386
    protected $flow_label = null;
1387
    /**
1388
     * @var cc_assesment_response_labeltype
1389
     */
1390
    protected $response_label = null;
1391
 
1392
    /** @var cc_assesment_material assesment material. */
1393
    protected $material;
1394
 
1395
    /** @var cc_assesment_response_matref assesment response material ref. */
1396
    protected $material_ref;
1397
 
1398
    public function __construct() {
1399
        $this->set_setting(cc_qti_tags::t_class);
1400
    }
1401
 
1402
    public function set_class($value) {
1403
        $this->set_setting(cc_qti_tags::t_class, $value);
1404
    }
1405
 
1406
    public function set_flow_label(cc_assesment_flow_labeltype $object) {
1407
        $this->flow_label = $object;
1408
    }
1409
 
1410
    public function set_response_label(cc_assesment_response_labeltype $object) {
1411
        $this->response_label = $object;
1412
    }
1413
 
1414
    public function generate(XMLGenericDocument &$doc, DOMNode &$item, $namespace) {
1415
        $node = $doc->append_new_element_ns($item, $namespace, cc_qti_tags::flow_label);
1416
        $this->generate_attributes($doc, $node, $namespace);
1417
 
1418
        if (!empty($this->material)) {
1419
            $this->material->generate($doc, $node, $namespace);
1420
        }
1421
 
1422
        if (!empty($this->material_ref)) {
1423
            $this->material_ref->generate($doc, $node, $namespace);
1424
        }
1425
 
1426
        if (!empty($this->response_label)) {
1427
            $this->response_label->generate($doc, $node, $namespace);
1428
        }
1429
 
1430
        if (!empty($this->flow_label)) {
1431
            $this->flow_label->generate($doc, $node, $namespace);
1432
        }
1433
    }
1434
 
1435
}
1436
 
1437
 
1438
class cc_assesment_render_fibtype extends cc_question_metadata_base {
1439
    /**
1440
     * @var cc_assesment_material
1441
     */
1442
    protected $material = null;
1443
 
1444
    /**
1445
     * @var cc_assesment_response_matref
1446
     */
1447
    protected $material_ref = null;
1448
    /**
1449
     * @var cc_assesment_response_labeltype
1450
     */
1451
    protected $response_label = null;
1452
    /**
1453
     *
1454
     * Enter description here ...
1455
     * @var unknown_type
1456
     */
1457
    protected $flow_label = null;
1458
 
1459
 
1460
    public function __construct() {
1461
        $this->set_setting(cc_qti_tags::encoding );
1462
        $this->set_setting(cc_qti_tags::charset  );
1463
        $this->set_setting(cc_qti_tags::rows     );
1464
        $this->set_setting(cc_qti_tags::columns  );
1465
        $this->set_setting(cc_qti_tags::maxchars );
1466
        $this->set_setting(cc_qti_tags::minnumber);
1467
        $this->set_setting(cc_qti_tags::maxnumber);
1468
        $this->set_setting(cc_qti_tags::prompt, cc_qti_values::Box);
1469
        $this->set_setting(cc_qti_tags::fibtype, cc_qti_values::String);
1470
    }
1471
 
1472
    public function set_encoding($value) {
1473
        $this->set_setting(cc_qti_tags::encoding, $value);
1474
    }
1475
    public function set_charset($value) {
1476
        $this->set_setting(cc_qti_tags::charset, $value);
1477
    }
1478
 
1479
    public function set_rows($value) {
1480
        $this->set_setting(cc_qti_tags::rows, $value);
1481
    }
1482
 
1483
    public function set_columns($value) {
1484
        $this->set_setting(cc_qti_tags::columns, $value);
1485
    }
1486
 
1487
    public function set_maxchars($value) {
1488
        $this->set_setting(cc_qti_tags::columns, $value);
1489
    }
1490
 
1491
    public function set_limits($min = null, $max = null) {
1492
        $this->set_setting(cc_qti_tags::minnumber, $min);
1493
        $this->set_setting(cc_qti_tags::maxnumber, $max);
1494
    }
1495
 
1496
    public function set_prompt($value) {
1497
        $this->set_setting(cc_qti_tags::prompt, $value);
1498
    }
1499
 
1500
    public function set_fibtype($value) {
1501
        $this->set_setting(cc_qti_tags::fibtype, $value);
1502
    }
1503
 
1504
    public function set_material(cc_assesment_material $object) {
1505
        $this->material = $object;
1506
    }
1507
 
1508
    public function set_material_ref(cc_assesment_response_matref $object) {
1509
        $this->material_ref = $object;
1510
    }
1511
 
1512
    public function set_response_label(cc_assesment_response_labeltype $object) {
1513
        $this->response_label = $object;
1514
    }
1515
 
1516
    public function set_flow_label($object) {
1517
        $this->flow_label = $object;
1518
    }
1519
 
1520
    public function generate(XMLGenericDocument &$doc, DOMNode &$item, $namespace) {
1521
        $node = $doc->append_new_element_ns($item, $namespace, cc_qti_tags::render_fib);
1522
        $this->generate_attributes($doc, $node, $namespace);
1523
 
1524
        if (!empty($this->material) && empty($this->material_ref)) {
1525
            $this->material->generate($doc, $node, $namespace);
1526
        }
1527
 
1528
        if (!empty($this->material_ref) && empty($this->material)) {
1529
            $this->material_ref->generate($doc, $node, $namespace);
1530
        }
1531
 
1532
        if (!empty($this->response_label)) {
1533
            $this->response_label->generate($doc, $node, $namespace);
1534
        }
1535
 
1536
        if (!empty($this->flow_label)) {
1537
            $this->flow_label->generate($doc, $node, $namespace);
1538
        }
1539
    }
1540
}
1541
 
1542
class cc_response_lidtype extends cc_question_metadata_base {
1543
    /**
1544
     * @var string
1545
     */
1546
    protected $tagname = null;
1547
    /**
1548
     * @var cc_assesment_material
1549
     */
1550
    protected $material = null;
1551
 
1552
    /**
1553
     * @var cc_assesment_response_matref
1554
     */
1555
    protected $material_ref = null;
1556
 
1557
    /**
1558
     * @var cc_assesment_render_choicetype
1559
     */
1560
    protected $render_choice = null;
1561
 
1562
    /**
1563
     * @var cc_assesment_render_fibtype
1564
     */
1565
    protected $render_fib = null;
1566
 
1567
    public function __construct() {
1568
        $this->set_setting(cc_qti_tags::rcardinality, cc_qti_values::Single);
1569
        $this->set_setting(cc_qti_tags::rtiming);
1570
        $this->set_setting(cc_qti_tags::ident, cc_helpers::uuidgen('I_'));
1571
        $this->tagname = cc_qti_tags::response_lid;
1572
    }
1573
 
1574
    public function set_rcardinality($value) {
1575
        $this->set_setting(cc_qti_tags::rcardinality, $value);
1576
    }
1577
 
1578
    public function enable_rtiming($value = true) {
1579
        $this->enable_setting_yesno(cc_qti_tags::rtiming, $value);
1580
    }
1581
 
1582
    public function set_ident($value) {
1583
        $this->set_setting(cc_qti_tags::ident, $value);
1584
    }
1585
 
1586
    public function get_ident() {
1587
        return $this->get_setting(cc_qti_tags::ident);
1588
    }
1589
 
1590
    public function set_material_ref(cc_assesment_response_matref $object) {
1591
        $this->material_ref = $object;
1592
    }
1593
 
1594
    public function set_material(cc_assesment_material $object) {
1595
        $this->material = $object;
1596
    }
1597
 
1598
    public function set_render_choice(cc_assesment_render_choicetype $object) {
1599
        $this->render_choice = $object;
1600
    }
1601
 
1602
    public function set_render_fib(cc_assesment_render_fibtype $object) {
1603
        $this->render_fib = $object;
1604
    }
1605
 
1606
    public function generate(XMLGenericDocument &$doc, DOMNode &$item, $namespace) {
1607
        $node = $doc->append_new_element_ns($item, $namespace, $this->tagname);
1608
        $this->generate_attributes($doc, $node, $namespace);
1609
 
1610
        if (!empty($this->material) && empty($this->material_ref)) {
1611
            $this->material->generate($doc, $node, $namespace);
1612
        }
1613
 
1614
        if (!empty($this->material_ref) && empty($this->material)) {
1615
            $this->material_ref->generate($doc, $node, $namespace);
1616
        }
1617
 
1618
        if (!empty($this->render_choice) && empty($this->render_fib)) {
1619
            $this->render_choice->generate($doc, $node, $namespace);
1620
        }
1621
 
1622
        if (!empty($this->render_fib) && empty($this->render_choice)) {
1623
            $this->render_fib->generate($doc, $node, $namespace);
1624
        }
1625
    }
1626
}
1627
 
1628
class cc_assesment_response_strtype extends cc_response_lidtype {
1629
    public function __construct() {
1630
        $rtt = parent::__construct();
1631
        $this->tagname = cc_qti_tags::response_str;
1632
    }
1633
}
1634
 
1635
class cc_assesment_flowtype extends cc_question_metadata_base {
1636
    /**
1637
     * @var cc_assesment_flowtype
1638
     */
1639
    protected $flow = null;
1640
    /**
1641
     * @var cc_assesment_material
1642
     */
1643
    protected $material = null;
1644
    /**
1645
     * @var cc_assesment_response_matref
1646
     */
1647
    protected $material_ref = null;
1648
    /**
1649
     * @var cc_response_lidtype
1650
     */
1651
    protected $response_lid = null;
1652
    /**
1653
     * @var cc_assesment_response_strtype
1654
     */
1655
    protected $response_str = null;
1656
 
1657
    public function __construct() {
1658
        $this->set_setting(cc_qti_tags::t_class);
1659
    }
1660
 
1661
    public function set_class($value) {
1662
        $this->set_setting(cc_qti_tags::t_class, $value);
1663
    }
1664
 
1665
    public function set_flow(cc_assesment_flowtype $object) {
1666
        $this->flow = $object;
1667
    }
1668
 
1669
    public function set_material(cc_assesment_material $object) {
1670
        $this->material = $object;
1671
    }
1672
 
1673
    public function set_material_ref(cc_assesment_response_matref $object) {
1674
        $this->material_ref = $object;
1675
    }
1676
 
1677
    public function set_response_lid(cc_response_lidtype $object) {
1678
        $this->response_lid = $object;
1679
    }
1680
 
1681
    public function set_response_str(cc_assesment_response_strtype $object) {
1682
        $this->response_str = $object;
1683
    }
1684
 
1685
    public function generate(XMLGenericDocument &$doc, DOMNode &$item, $namespace) {
1686
        $node = $doc->append_new_element_ns($item, $namespace, cc_qti_tags::flow);
1687
        $this->generate_attributes($doc, $node, $namespace);
1688
 
1689
        if (!empty($this->flow)) {
1690
            $this->flow->generate($doc, $node, $namespace);
1691
        }
1692
 
1693
        if (!empty($this->material)) {
1694
            $this->material->generate($doc, $node, $namespace);
1695
        }
1696
 
1697
        if (!empty($this->response_lid)) {
1698
            $this->response_lid->generate($doc, $node, $namespace);
1699
        }
1700
 
1701
        if (!empty($this->response_str)) {
1702
            $this->response_str->generate($doc, $node, $namespace);
1703
        }
1704
    }
1705
}
1706
 
1707
class cc_assesment_presentation extends cc_question_metadata_base {
1708
    /**
1709
     * @var cc_assesment_flowtype
1710
     */
1711
    protected $flow         = null;
1712
    /**
1713
     * @var cc_assesment_material
1714
     */
1715
    protected $material     = null;
1716
    /**
1717
     * @var cc_response_lidtype
1718
     */
1719
    protected $response_lid = null;
1720
    /**
1721
     * @var cc_assesment_response_strtype
1722
     */
1723
    protected $response_str = null;
1724
 
1725
    public function __construct() {
1726
        $this->set_setting(cc_qti_tags::label);
1727
        $this->set_setting_wns(cc_qti_tags::xml_lang , cc_xml_namespace::xml);
1728
        $this->set_setting(cc_qti_tags::x0);
1729
        $this->set_setting(cc_qti_tags::y0);
1730
        $this->set_setting(cc_qti_tags::width);
1731
        $this->set_setting(cc_qti_tags::height);
1732
    }
1733
 
1734
    public function set_label($value) {
1735
        $this->set_setting(cc_qti_tags::label, $value);
1736
    }
1737
 
1738
    public function set_lang($value) {
1739
        $this->set_setting_wns(cc_qti_tags::xml_lang , cc_xml_namespace::xml, $value);
1740
    }
1741
 
1742
    public function set_coor($x = null, $y = null) {
1743
        $this->set_setting(cc_qti_tags::x0, $x);
1744
        $this->set_setting(cc_qti_tags::y0, $y);
1745
    }
1746
 
1747
    public function set_size($width = null, $height = null) {
1748
        $this->set_setting(cc_qti_tags::width, $width);
1749
        $this->set_setting(cc_qti_tags::height, $height);
1750
    }
1751
 
1752
    public function set_flow(cc_assesment_flowtype $object) {
1753
        $this->flow = $object;
1754
    }
1755
 
1756
    public function set_material(cc_assesment_material $object) {
1757
        $this->material = $object;
1758
    }
1759
 
1760
    public function set_response_lid(cc_response_lidtype $object) {
1761
        $this->response_lid = $object;
1762
    }
1763
 
1764
    public function set_response_str(cc_assesment_response_strtype $object) {
1765
        $this->response_str = $object;
1766
    }
1767
 
1768
    public function generate(XMLGenericDocument &$doc, DOMNode &$item, $namespace) {
1769
        $node = $doc->append_new_element_ns($item, $namespace, cc_qti_tags::presentation);
1770
        $this->generate_attributes($doc, $node, $namespace);
1771
 
1772
        if (!empty($this->flow)) {
1773
            $this->flow->generate($doc, $node, $namespace);
1774
        }
1775
 
1776
        if (!empty($this->material) && empty($this->flow)) {
1777
            $this->material->generate($doc, $node, $namespace);
1778
        }
1779
 
1780
        if (!empty($this->response_lid) && empty($this->flow)) {
1781
            $this->response_lid->generate($doc, $node, $namespace);
1782
        }
1783
 
1784
        if (!empty($this->response_str) && empty($this->flow)) {
1785
            $this->response_str->generate($doc, $node, $namespace);
1786
        }
1787
    }
1788
}
1789
 
1790
class assesment1_resurce_file extends general_cc_file {
1791
    const deafultname = 'assesment.xml';
1792
 
1793
    protected $rootns   = 'xmlns';
1794
    protected $rootname = cc_qti_tags::questestinterop;
1795
    protected $ccnamespaces = array('xmlns' => 'http://www.imsglobal.org/xsd/ims_qtiasiv1p2',
1796
                                    'xsi'   => 'http://www.w3.org/2001/XMLSchema-instance');
1797
    protected $ccnsnames = array('xmlns' => 'http://www.imsglobal.org/profile/cc/ccv1p0/derived_schema/domainProfile_4/ims_qtiasiv1p2_localised.xsd');
1798
 
1799
    /**
1800
     * @var string
1801
     */
1802
    protected $assessment_title = 'Untitled';
1803
    /**
1804
     * @var cc_assesment_metadata
1805
     */
1806
    protected $metadata = null;
1807
    /**
1808
     * @var cc_assesment_rubric_base
1809
     */
1810
    protected $rubric = null;
1811
 
1812
    /**
1813
     * @var cc_assesment_presentation_material_base
1814
     */
1815
    protected $presentation_material = null;
1816
 
1817
    /**
1818
     * @var cc_assesment_section
1819
     */
1820
    protected $section = null;
1821
 
1822
    public function set_metadata(cc_assesment_metadata $object) {
1823
        $this->metadata = $object;
1824
    }
1825
 
1826
    public function set_rubric(cc_assesment_rubric_base $object) {
1827
        $this->rubric = $object;
1828
    }
1829
 
1830
    public function set_presentation_material(cc_assesment_presentation_material_base $object) {
1831
        $this->presentation_material = $object;
1832
    }
1833
 
1834
    public function set_section(cc_assesment_section $object) {
1835
        $this->section = $object;
1836
    }
1837
 
1838
    public function set_title($value) {
1839
        $this->assessment_title = self::safexml($value);
1840
    }
1841
 
1842
    protected function on_save() {
1843
        $rns = $this->ccnamespaces[$this->rootns];
1844
        //root assesment element - required
1845
        $assessment = $this->append_new_element_ns($this->root, $rns, cc_qti_tags::assessment);
1846
        $this->append_new_attribute_ns($assessment, $rns, cc_qti_tags::ident, cc_helpers::uuidgen('QDB_'));
1847
        $this->append_new_attribute_ns($assessment, $rns, cc_qti_tags::title, $this->assessment_title);
1848
 
1849
        //metadata - optional
1850
        if (!empty($this->metadata)) {
1851
            $this->metadata->generate($this, $assessment, $rns);
1852
        }
1853
 
1854
        //rubric - optional
1855
        if (!empty($this->rubric)) {
1856
            $this->rubric->generate($this, $assessment, $rns);
1857
        }
1858
 
1859
        //presentation_material - optional
1860
        if (!empty($this->presentation_material)) {
1861
            $this->presentation_material->generate($this, $assessment, $rns);
1862
        }
1863
 
1864
        //section - required
1865
        if (!empty($this->section)) {
1866
            $this->section->generate($this, $assessment, $rns);
1867
        }
1868
 
1869
        return true;
1870
    }
1871
}
1872
 
1873
 
1874
class assesment11_resurce_file extends assesment1_resurce_file {
1875
    protected $ccnsnames = array('xmlns' => 'http://www.imsglobal.org/profile/cc/ccv1p1/ccv1p1_qtiasiv1p2p1_v1p0.xsd');
1876
}
1877
 
1878
abstract class cc_assesment_helper {
1879
 
1880
    public static $correct_fb = null;
1881
    public static $incorrect_fb = null;
1882
 
1883
    public static function add_feedback($qitem, $content, $content_type, $ident) {
1884
        if (empty($content)) {
1885
            return false;
1886
        }
1887
        $qitemfeedback = new cc_assesment_itemfeedbacktype();
1888
        $qitem->add_itemfeedback($qitemfeedback);
1889
        if (!empty($ident)) {
1890
            $qitemfeedback->set_ident($ident);
1891
        }
1892
        $qflowmat = new cc_assesment_flow_mattype();
1893
        $qitemfeedback->set_flow_mat($qflowmat);
1894
        $qmaterialfb = new cc_assesment_material();
1895
        $qflowmat->set_material($qmaterialfb);
1896
        $qmattext = new cc_assesment_mattext();
1897
        $qmaterialfb->set_mattext($qmattext);
1898
        $qmattext->set_content($content, $content_type);
1899
        return true;
1900
    }
1901
 
1902
    public static function add_answer($qresponse_choice, $content, $content_type) {
1903
        $qresponse_label = new cc_assesment_response_labeltype();
1904
        $qresponse_choice->add_response_label($qresponse_label);
1905
        $qrespmaterial = new cc_assesment_material();
1906
        $qresponse_label->set_material($qrespmaterial);
1907
        $qrespmattext = new cc_assesment_mattext();
1908
        $qrespmaterial->set_mattext($qrespmattext);
1909
        $qrespmattext->set_content($content, $content_type);
1910
        return $qresponse_label;
1911
    }
1912
 
1913
    public static function add_response_condition($node, $title, $ident, $feedback_refid, $respident) {
1914
        $qrespcondition = new cc_assesment_respconditiontype();
1915
        $node->add_respcondition($qrespcondition);
1916
        //define rest of the conditions
1917
        $qconditionvar = new cc_assignment_conditionvar();
1918
        $qrespcondition->set_conditionvar($qconditionvar);
1919
        $qvarequal = new cc_assignment_conditionvar_varequaltype($ident);
1920
        $qvarequal->enable_case();
1921
        $qconditionvar->set_varequal($qvarequal);
1922
        $qvarequal->set_respident($respident);
1923
        $qdisplayfeedback = new cc_assignment_displayfeedbacktype();
1924
        $qrespcondition->add_displayfeedback($qdisplayfeedback);
1925
        $qdisplayfeedback->set_feedbacktype(cc_qti_values::Response);
1926
        $qdisplayfeedback->set_linkrefid($feedback_refid);
1927
    }
1928
 
1929
    public static function add_assesment_description($rt, $content, $contenttype) {
1930
        if (empty($rt) || empty($content)) {
1931
            return;
1932
        }
1933
        $activity_rubric = new cc_assesment_rubric_base();
1934
        $rubric_material = new cc_assesment_material();
1935
        $activity_rubric->set_material($rubric_material);
1936
        $rubric_mattext = new cc_assesment_mattext();
1937
        $rubric_material->set_label('Summary');
1938
        $rubric_material->set_mattext($rubric_mattext);
1939
        $rubric_mattext->set_content($content, $contenttype);
1940
        $rt->set_rubric($activity_rubric);
1941
    }
1942
 
1943
    public static function add_respcondition($node, $title, $feedback_refid, $grade_value = null, $continue = false ) {
1944
        $qrespcondition = new cc_assesment_respconditiontype();
1945
        $qrespcondition->set_title($title);
1946
        $node->add_respcondition($qrespcondition);
1947
        $qrespcondition->enable_continue($continue);
1948
        //Add setvar if grade present
1949
        if ($grade_value !== null) {
1950
            $qsetvar = new cc_assignment_setvartype($grade_value);
1951
            $qrespcondition->add_setvar($qsetvar);
1952
        }
1953
        //define the condition for success
1954
        $qconditionvar = new cc_assignment_conditionvar();
1955
        $qrespcondition->set_conditionvar($qconditionvar);
1956
        $qother = new cc_assignment_conditionvar_othertype();
1957
        $qconditionvar->set_other($qother);
1958
        $qdisplayfeedback = new cc_assignment_displayfeedbacktype();
1959
        $qrespcondition->add_displayfeedback($qdisplayfeedback);
1960
        $qdisplayfeedback->set_feedbacktype(cc_qti_values::Response);
1961
        $qdisplayfeedback->set_linkrefid($feedback_refid);
1962
    }
1963
 
1964
    /**
1965
     *
1966
     * Enter description here ...
1967
     * @param XMLGenericDocument $qdoc
1968
     * @param unknown_type $manifest
1969
     * @param cc_assesment_section $section
1970
     * @param unknown_type $rootpath
1971
     * @param unknown_type $contextid
1972
     * @param unknown_type $outdir
1973
     */
1974
    public static function process_questions(&$qdoc, &$manifest, cc_assesment_section &$section, $rootpath, $contextid, $outdir) {
1975
        $question_file = $rootpath . DIRECTORY_SEPARATOR . 'questions.xml';
1976
        //load questions file
1977
        $questions = new XMLGenericDocument();
1978
        if (!$questions->load($question_file)) {
1979
            return false;
1980
        }
1981
 
1982
        pkg_resource_dependencies::instance()->reset();
1983
        $questioncount = 0;
1984
        $questionforexport = 0;
1985
        $qids = $qdoc->nodeList('//question_instances//questionid');
1986
        foreach ($qids as $qid) {
1987
            /** @var DOMNode $qid */
1988
            $value = $qid->nodeValue;
1989
            if (intval($value) == 0) {
1990
                continue;
1991
            }
1992
            $question_node = $questions->node("//question_category/questions/question[@id='{$value}']");
1993
            if (empty($question_node)) {
1994
                continue;
1995
            }
1996
            ++$questionforexport;
1997
            //process question
1998
            //question type
1999
            $qtype = $questions->nodeValue('qtype', $question_node);
2000
            $question_processor = null;
2001
            switch ($qtype) {
2002
                case 'multichoice':
2003
                    $single_correct_answer = (int)$questions->nodeValue('plugin_qtype_multichoice_question/multichoice/single', $question_node) > 0;
2004
                    //TODO: Add checking for the nunmber of valid responses
2005
                    //If question is marked as multi response but contains only one valid answer it
2006
                    //should be handle as single response - classic multichoice
2007
                    if ($single_correct_answer) {
2008
                        $question_processor = new cc_assesment_question_multichoice($qdoc, $questions, $manifest, $section, $question_node, $rootpath, $contextid, $outdir);
2009
                    } else {
2010
                        $question_processor = new cc_assesment_question_multichoice_multiresponse($qdoc, $questions, $manifest, $section, $question_node, $rootpath, $contextid, $outdir);
2011
                    }
2012
                    $question_processor->generate();
2013
                    ++$questioncount;
2014
                break;
2015
                case 'truefalse':
2016
                    $question_processor = new cc_assesment_question_truefalse($qdoc, $questions, $manifest, $section, $question_node, $rootpath, $contextid, $outdir);
2017
                    $question_processor->generate();
2018
                    ++$questioncount;
2019
                break;
2020
                case 'essay':
2021
                    $question_processor = new cc_assesment_question_essay($qdoc, $questions, $manifest, $section, $question_node, $rootpath, $contextid, $outdir);
2022
                    $question_processor->generate();
2023
                    ++$questioncount;
2024
                break;
2025
                case 'shortanswer':
2026
                    //This is rather ambiguos since shortanswer supports partial pattern match
2027
                    //In order to detect pattern match we need to scan for all the responses
2028
                    //if at least one of the responses uses wildcards it should be treated as
2029
                    //pattern match, otherwise it should be simple fill in the blank
2030
                    if (self::has_matching_element($questions, $question_node)) {
2031
                        //$question_processor = new cc_assesment_question_patternmatch($qdoc, $questions, $manifest, $section, $question_node, $rootpath, $contextid, $outdir);
2032
                        $questionforexport--;
2033
                    } else {
2034
                        $question_processor = new cc_assesment_question_sfib($qdoc, $questions, $manifest, $section, $question_node, $rootpath, $contextid, $outdir);
2035
                    }
2036
                    if (!empty($question_processor)) {
2037
                        $question_processor->generate();
2038
                        ++$questioncount;
2039
                    }
2040
                break;
2041
                default:
2042
                    ;
2043
                break;
2044
            }
2045
 
2046
        }
2047
 
2048
        //return dependencies
2049
        return ($questioncount == 0) || ($questioncount != $questionforexport)?
2050
               false: pkg_resource_dependencies::instance()->get_deps();
2051
    }
2052
 
2053
    /**
2054
     *
2055
     * Checks if question has matching element
2056
     * @param XMLGenericDocument $questions
2057
     * @param object $question_node
2058
     * @return bool
2059
     */
2060
    public static function has_matching_element(XMLGenericDocument $questions, $question_node) {
2061
        $answers = $questions->nodeList('plugin_qtype_shortanswer_question//answertext', $question_node);
2062
        $result = false;
2063
        foreach ($answers as $answer) {
2064
            $prepare = str_replace('\*', '\#', $answer->nodeValue);
2065
            $result = (strpos($prepare, '*') !== false);
2066
            if ($result) {
2067
                break;
2068
            }
2069
        }
2070
        return $result;
2071
    }
2072
 
2073
}
2074
 
2075
class cc_assesment_question_proc_base {
2076
    /**
2077
     * @var XMLGenericDocument
2078
     */
2079
    protected $quiz = null;
2080
 
2081
    /**
2082
     * @var XMLGenericDocument
2083
     */
2084
    protected $questions = null;
2085
 
2086
    /**
2087
    * @var cc_manifest
2088
    */
2089
    protected $manifest = null;
2090
 
2091
    /**
2092
     * @var cc_assesment_section
2093
     */
2094
    protected $section = null;
2095
 
2096
    /**
2097
     * @var DOMElement
2098
     */
2099
    protected $question_node = null;
2100
 
2101
    /**
2102
     * @var string
2103
     */
2104
    protected $rootpath = null;
2105
 
2106
    /**
2107
     * @var string
2108
     */
2109
    protected $contextid = null;
2110
 
2111
    /**
2112
     * @var string
2113
     */
2114
    protected $outdir = null;
2115
 
2116
    /**
2117
     * @var string
2118
     */
2119
    protected $qtype = null;
2120
 
2121
    /**
2122
     * @var cc_question_metadata
2123
     */
2124
    protected $qmetadata = null;
2125
 
2126
    /**
2127
     * @var cc_assesment_section_item
2128
     */
2129
    protected $qitem = null;
2130
 
2131
    /**
2132
     * @var cc_assesment_presentation
2133
     */
2134
    protected $qpresentation = null;
2135
 
2136
    /**
2137
     * @var cc_response_lidtype
2138
     */
2139
    protected $qresponse_lid = null;
2140
 
2141
    protected $qresprocessing = null;
2142
 
2143
    protected $correct_grade_value = null;
2144
    protected $correct_answer_node_id = null;
2145
    protected $correct_answer_ident = null;
2146
 
2147
    protected $total_grade_value = null;
2148
 
2149
    protected $answerlist = null;
2150
 
2151
    protected $general_feedback = null;
2152
    protected $correct_feedbacks = array();
2153
    protected $incorrect_feedbacks = array();
2154
 
2155
    /**
2156
     * @param XMLGenericDocument $questions
2157
     * @param cc_manifest $manifest
2158
     * @param cc_assesment_section $section
2159
     * @param DOMElement $question_node
2160
     * @param string $rootpath
2161
     * @param string $contextid
2162
     * @param string $outdir
2163
     */
2164
    public function __construct(XMLGenericDocument &$quiz, XMLGenericDocument &$questions, cc_manifest &$manifest, cc_assesment_section &$section, &$question_node, $rootpath, $contextid, $outdir) {
2165
        $this->quiz = $quiz;
2166
        $this->questions = $questions;
2167
        $this->manifest = $manifest;
2168
        $this->section = $section;
2169
        $this->question_node = $question_node;
2170
        $this->rootpath = $rootpath;
2171
        $this->contextid = $contextid;
2172
        $this->outdir = $outdir;
2173
 
2174
        //
2175
        $qitem = new cc_assesment_section_item();
2176
        $this->section->add_item($qitem);
2177
        $qitem->set_title($this->questions->nodeValue('name', $this->question_node));
2178
        $this->qitem = $qitem;
2179
    }
2180
 
2181
    public function on_generate_metadata() {
2182
        if (empty($this->qmetadata)) {
2183
            $this->qmetadata = new cc_question_metadata($this->qtype);
2184
            //Get weighting value
2185
            $weighting_value = (int)$this->questions->nodeValue('defaultmark', $this->question_node);
2186
            if ($weighting_value > 1) {
2187
                $this->qmetadata->set_weighting($weighting_value);
2188
            }
2189
            //Get category
2190
            $question_category = $this->questions->nodeValue('../../name', $this->question_node);
2191
            if (!empty($question_category)) {
2192
                $this->qmetadata->set_category($question_category);
2193
            }
2194
            $rts = new cc_assesment_itemmetadata();
2195
            $rts->add_metadata($this->qmetadata);
2196
            $this->qitem->set_itemmetadata($rts);
2197
        }
2198
    }
2199
 
2200
    public function on_generate_presentation() {
2201
        if (empty($this->qpresentation)) {
2202
            $qpresentation = new cc_assesment_presentation();
2203
            $this->qitem->set_presentation($qpresentation);
2204
            //add question text
2205
            $qmaterial = new cc_assesment_material();
2206
            $qmattext = new cc_assesment_mattext();
2207
            $question_text = $this->questions->nodeValue('questiontext', $this->question_node);
2208
            $result = cc_helpers::process_linked_files( $question_text,
2209
                                                        $this->manifest,
2210
                                                        $this->rootpath,
2211
                                                        $this->contextid,
2212
                                                        $this->outdir);
2213
            $qmattext->set_content($result[0], cc_qti_values::htmltype);
2214
            $qmaterial->set_mattext($qmattext);
2215
            $qpresentation->set_material($qmaterial);
2216
            $this->qpresentation = $qpresentation;
2217
            pkg_resource_dependencies::instance()->add($result[1]);
2218
        }
2219
    }
2220
 
2221
    public function on_generate_answers() {}
2222
    public function on_generate_feedbacks() {
2223
        $general_question_feedback = $this->questions->nodeValue('generalfeedback', $this->question_node);
2224
        if (empty($general_question_feedback)) {
2225
            return;
2226
        }
2227
        $name = 'general_fb';
2228
        //Add question general feedback - the one that should be always displayed
2229
        $result = cc_helpers::process_linked_files( $general_question_feedback,
2230
                                                    $this->manifest,
2231
                                                    $this->rootpath,
2232
                                                    $this->contextid,
2233
                                                    $this->outdir);
2234
 
2235
        cc_assesment_helper::add_feedback($this->qitem,
2236
                                          $result[0],
2237
                                          cc_qti_values::htmltype,
2238
                                          $name);
2239
        pkg_resource_dependencies::instance()->add($result[1]);
2240
        $this->general_feedback = $name;
2241
    }
2242
 
2243
    public function on_generate_response_processing() {
2244
 
2245
        $qresprocessing = new cc_assesment_resprocessingtype();
2246
        $this->qitem->add_resprocessing($qresprocessing);
2247
        $qdecvar = new cc_assesment_decvartype();
2248
        $qresprocessing->set_decvar($qdecvar);
2249
        //according to the Common Cartridge 1.1 Profile: Implementation document
2250
        //this should always be set to 0, 100 in case of question type that is not essay
2251
        $qdecvar->set_limits(0,100);
2252
        $qdecvar->set_vartype(cc_qti_values::Decimal);
2253
 
2254
        $this->qresprocessing = $qresprocessing;
2255
 
2256
    }
2257
 
2258
    public function generate() {
2259
        $this->on_generate_metadata();
2260
 
2261
        $this->on_generate_presentation();
2262
 
2263
        $this->on_generate_answers();
2264
 
2265
        $this->on_generate_feedbacks();
2266
 
2267
        $this->on_generate_response_processing();
2268
    }
2269
 
2270
}
2271
 
2272
class cc_assesment_question_multichoice extends cc_assesment_question_proc_base {
2273
    public function __construct($quiz, $questions, $manifest, $section, $question_node, $rootpath, $contextid, $outdir) {
2274
        parent::__construct($quiz, $questions, $manifest, $section, $question_node, $rootpath, $contextid, $outdir);
2275
        $this->qtype = cc_qti_profiletype::multiple_choice;
2276
 
2277
        /**
2278
         *
2279
         * What is needed is a maximum grade value taken from the answer fraction
2280
         * It is supposed to always be between 1 and 0 in decimal representation,
2281
         * however that is not always the case so a change in test was needed
2282
         * but since we support here one correct answer type
2283
         * correct answer would always have to be 1
2284
         */
2285
        $correct_answer_node = $this->questions->node("plugin_qtype_multichoice_question/answers/answer[fraction > 0]", $this->question_node);
2286
        if (empty($correct_answer_node)) {
2287
            throw new RuntimeException('No correct answer!');
2288
        }
2289
        $this->correct_answer_node_id = $this->questions->nodeValue('@id', $correct_answer_node);
2290
        $maximum_quiz_grade = (int)$this->quiz->nodeValue('/activity/quiz/grade');
2291
        $this->total_grade_value = ($maximum_quiz_grade + 1).'.0000000';
2292
    }
2293
 
2294
    public function on_generate_answers() {
2295
        //add responses holder
2296
        $qresponse_lid = new cc_response_lidtype();
2297
        $this->qresponse_lid = $qresponse_lid;
2298
        $this->qpresentation->set_response_lid($qresponse_lid);
2299
        $qresponse_choice = new cc_assesment_render_choicetype();
2300
        $qresponse_lid->set_render_choice($qresponse_choice);
2301
        //Mark that question has only one correct answer -
2302
        //which applies for multiple choice and yes/no questions
2303
        $qresponse_lid->set_rcardinality(cc_qti_values::Single);
2304
        //are we to shuffle the responses?
2305
        $shuffle_answers = (int)$this->quiz->nodeValue('/activity/quiz/shuffleanswers') > 0;
2306
        $qresponse_choice->enable_shuffle($shuffle_answers);
2307
        $answerlist = array();
2308
        $qa_responses = $this->questions->nodeList('plugin_qtype_multichoice_question/answers/answer', $this->question_node);
2309
        foreach ($qa_responses as $node) {
2310
            $answer_content = $this->questions->nodeValue('answertext', $node);
2311
            $id = ((int)$this->questions->nodeValue('@id', $node) == $this->correct_answer_node_id);
2312
            $result = cc_helpers::process_linked_files( $answer_content,
2313
                                                        $this->manifest,
2314
                                                        $this->rootpath,
2315
                                                        $this->contextid,
2316
                                                        $this->outdir);
2317
            $qresponse_label = cc_assesment_helper::add_answer( $qresponse_choice,
2318
                                                                $result[0],
2319
                                                                cc_qti_values::htmltype);
2320
            pkg_resource_dependencies::instance()->add($result[1]);
2321
            $answer_ident = $qresponse_label->get_ident();
2322
            $feedback_ident = $answer_ident.'_fb';
2323
            if (empty($this->correct_answer_ident) && $id) {
2324
                $this->correct_answer_ident = $answer_ident;
2325
            }
2326
            //add answer specific feedbacks if not empty
2327
            $content = $this->questions->nodeValue('feedback', $node);
2328
            if (!empty($content)) {
2329
                $result = cc_helpers::process_linked_files( $content,
2330
                                                            $this->manifest,
2331
                                                            $this->rootpath,
2332
                                                            $this->contextid,
2333
                                                            $this->outdir);
2334
 
2335
 
2336
                cc_assesment_helper::add_feedback( $this->qitem,
2337
                                                   $result[0],
2338
                                                   cc_qti_values::htmltype,
2339
                                                   $feedback_ident);
2340
 
2341
                pkg_resource_dependencies::instance()->add($result[1]);
2342
 
2343
                $answerlist[$answer_ident] = $feedback_ident;
2344
            }
2345
        }
2346
 
2347
        $this->answerlist = $answerlist;
2348
 
2349
    }
2350
 
2351
    public function on_generate_feedbacks() {
2352
        parent::on_generate_feedbacks();
2353
        //Question combined feedbacks
2354
        $correct_question_fb = $this->questions->nodeValue('plugin_qtype_multichoice_question/multichoice/correctfeedback', $this->question_node);
2355
        $incorrect_question_fb = $this->questions->nodeValue('plugin_qtype_multichoice_question/multichoice/incorrectfeedback', $this->question_node);
2356
        $proc = array('correct_fb' => $correct_question_fb, 'general_incorrect_fb' => $incorrect_question_fb);
2357
        foreach ($proc as $ident => $content) {
2358
            if (empty($content)) {
2359
                continue;
2360
            }
2361
            $result = cc_helpers::process_linked_files( $content,
2362
                                                        $this->manifest,
2363
                                                        $this->rootpath,
2364
                                                        $this->contextid,
2365
                                                        $this->outdir);
2366
 
2367
            cc_assesment_helper::add_feedback( $this->qitem,
2368
                                               $result[0],
2369
                                               cc_qti_values::htmltype,
2370
                                               $ident);
2371
 
2372
            pkg_resource_dependencies::instance()->add($result[1]);
2373
            if ($ident == 'correct_fb') {
2374
                $this->correct_feedbacks[] = $ident;
2375
            } else {
2376
                $this->incorrect_feedbacks[] = $ident;
2377
            }
2378
        }
2379
 
2380
    }
2381
 
2382
    public function on_generate_response_processing() {
2383
        parent::on_generate_response_processing();
2384
 
2385
        //respconditions
2386
        /**
2387
         * General unconditional feedback must be added as a first respcondition
2388
         * without any condition and just displayfeedback (if exists)
2389
         */
2390
        if (!empty($this->general_feedback)) {
2391
            $qrespcondition = new cc_assesment_respconditiontype();
2392
            $qrespcondition->set_title('General feedback');
2393
            $this->qresprocessing->add_respcondition($qrespcondition);
2394
            $qrespcondition->enable_continue();
2395
            //define the condition for success
2396
            $qconditionvar = new cc_assignment_conditionvar();
2397
            $qrespcondition->set_conditionvar($qconditionvar);
2398
            $qother = new cc_assignment_conditionvar_othertype();
2399
            $qconditionvar->set_other($qother);
2400
            $qdisplayfeedback = new cc_assignment_displayfeedbacktype();
2401
            $qrespcondition->add_displayfeedback($qdisplayfeedback);
2402
            $qdisplayfeedback->set_feedbacktype(cc_qti_values::Response);
2403
            $qdisplayfeedback->set_linkrefid('general_fb');
2404
        }
2405
 
2406
        //success condition
2407
        /**
2408
         * For all question types outside of the Essay question, scoring is done in a
2409
         * single <respcondition> with a continue flag set to No. The outcome is always
2410
         * a variable named SCORE which value must be set to 100 in case of correct answer.
2411
         * Partial scores (not 0 or 100) are not supported.
2412
         */
2413
        $qrespcondition = new cc_assesment_respconditiontype();
2414
        $qrespcondition->set_title('Correct');
2415
        $this->qresprocessing->add_respcondition($qrespcondition);
2416
        $qrespcondition->enable_continue(false);
2417
        $qsetvar = new cc_assignment_setvartype(100);
2418
        $qrespcondition->add_setvar($qsetvar);
2419
        //define the condition for success
2420
        $qconditionvar = new cc_assignment_conditionvar();
2421
        $qrespcondition->set_conditionvar($qconditionvar);
2422
        $qvarequal = new cc_assignment_conditionvar_varequaltype($this->correct_answer_ident);
2423
        $qconditionvar->set_varequal($qvarequal);
2424
        $qvarequal->set_respident($this->qresponse_lid->get_ident());
2425
 
2426
        if (array_key_exists($this->correct_answer_ident, $this->answerlist)) {
2427
            $qdisplayfeedback = new cc_assignment_displayfeedbacktype();
2428
            $qrespcondition->add_displayfeedback($qdisplayfeedback);
2429
            $qdisplayfeedback->set_feedbacktype(cc_qti_values::Response);
2430
            $qdisplayfeedback->set_linkrefid($this->answerlist[$this->correct_answer_ident]);
2431
        }
2432
 
2433
        foreach ($this->correct_feedbacks as $ident) {
2434
            $qdisplayfeedback = new cc_assignment_displayfeedbacktype();
2435
            $qrespcondition->add_displayfeedback($qdisplayfeedback);
2436
            $qdisplayfeedback->set_feedbacktype(cc_qti_values::Response);
2437
            $qdisplayfeedback->set_linkrefid($ident);
2438
        }
2439
 
2440
        //rest of the conditions
2441
        foreach ($this->answerlist as $ident => $refid) {
2442
            if ($ident == $this->correct_answer_ident) {
2443
                continue;
2444
            }
2445
 
2446
            $qrespcondition = new cc_assesment_respconditiontype();
2447
            $this->qresprocessing->add_respcondition($qrespcondition);
2448
            $qsetvar = new cc_assignment_setvartype(0);
2449
            $qrespcondition->add_setvar($qsetvar);
2450
            //define the condition for fail
2451
            $qconditionvar = new cc_assignment_conditionvar();
2452
            $qrespcondition->set_conditionvar($qconditionvar);
2453
            $qvarequal = new cc_assignment_conditionvar_varequaltype($ident);
2454
            $qconditionvar->set_varequal($qvarequal);
2455
            $qvarequal->set_respident($this->qresponse_lid->get_ident());
2456
 
2457
            $qdisplayfeedback = new cc_assignment_displayfeedbacktype();
2458
            $qrespcondition->add_displayfeedback($qdisplayfeedback);
2459
            $qdisplayfeedback->set_feedbacktype(cc_qti_values::Response);
2460
            $qdisplayfeedback->set_linkrefid($refid);
2461
 
2462
            foreach ($this->incorrect_feedbacks as $ident) {
2463
                $qdisplayfeedback = new cc_assignment_displayfeedbacktype();
2464
                $qrespcondition->add_displayfeedback($qdisplayfeedback);
2465
                $qdisplayfeedback->set_feedbacktype(cc_qti_values::Response);
2466
                $qdisplayfeedback->set_linkrefid($ident);
2467
            }
2468
        }
2469
    }
2470
}
2471
 
2472
class cc_assesment_question_multichoice_multiresponse extends cc_assesment_question_proc_base {
2473
    /**
2474
     * @var DOMNodeList
2475
     */
2476
    protected $correct_answers = null;
2477
 
2478
    public function __construct($quiz, $questions, $manifest, $section, $question_node, $rootpath, $contextid, $outdir) {
2479
        parent::__construct($quiz, $questions, $manifest, $section, $question_node, $rootpath, $contextid, $outdir);
2480
        $this->qtype = cc_qti_profiletype::multiple_response;
2481
 
2482
        $correct_answer_nodes = $this->questions->nodeList("plugin_qtype_multichoice_question/answers/answer[fraction > 0]", $this->question_node);
2483
        if ($correct_answer_nodes->length == 0) {
2484
            throw new RuntimeException('No correct answer!');
2485
        }
2486
        $this->correct_answers = $correct_answer_nodes;
2487
        //$this->correct_answer_node_id = $this->questions->nodeValue('@id', $correct_answer_node);
2488
        $maximum_quiz_grade = (int)$this->quiz->nodeValue('/activity/quiz/grade');
2489
        $this->total_grade_value = ($maximum_quiz_grade + 1).'.0000000';
2490
    }
2491
 
2492
    public function on_generate_answers() {
2493
        //add responses holder
2494
        $qresponse_lid = new cc_response_lidtype();
2495
        $this->qresponse_lid = $qresponse_lid;
2496
        $this->qpresentation->set_response_lid($qresponse_lid);
2497
        $qresponse_choice = new cc_assesment_render_choicetype();
2498
        $qresponse_lid->set_render_choice($qresponse_choice);
2499
        //Mark that question has more than one correct answer
2500
        $qresponse_lid->set_rcardinality(cc_qti_values::Multiple);
2501
        //are we to shuffle the responses?
2502
        $shuffle_answers = (int)$this->quiz->nodeValue('/activity/quiz/shuffleanswers') > 0;
2503
        $qresponse_choice->enable_shuffle($shuffle_answers);
2504
        $answerlist = array();
2505
        $qa_responses = $this->questions->nodeList('plugin_qtype_multichoice_question/answers/answer', $this->question_node);
2506
        foreach ($qa_responses as $node) {
2507
            $answer_content = $this->questions->nodeValue('answertext', $node);
2508
            $answer_grade_fraction = (float)$this->questions->nodeValue('fraction', $node);
2509
            $result = cc_helpers::process_linked_files( $answer_content,
2510
                                                        $this->manifest,
2511
                                                        $this->rootpath,
2512
                                                        $this->contextid,
2513
                                                        $this->outdir);
2514
            $qresponse_label = cc_assesment_helper::add_answer( $qresponse_choice,
2515
                                                                $result[0],
2516
                                                                cc_qti_values::htmltype);
2517
            pkg_resource_dependencies::instance()->add($result[1]);
2518
            $answer_ident = $qresponse_label->get_ident();
2519
            $feedback_ident = $answer_ident.'_fb';
2520
            //add answer specific feedbacks if not empty
2521
            $content = $this->questions->nodeValue('feedback', $node);
2522
            if (!empty($content)) {
2523
                $result = cc_helpers::process_linked_files( $content,
2524
                                                            $this->manifest,
2525
                                                            $this->rootpath,
2526
                                                            $this->contextid,
2527
                                                            $this->outdir);
2528
 
2529
 
2530
                cc_assesment_helper::add_feedback( $this->qitem,
2531
                                                    $result[0],
2532
                                                    cc_qti_values::htmltype,
2533
                                                    $feedback_ident);
2534
 
2535
                pkg_resource_dependencies::instance()->add($result[1]);
2536
 
2537
            }
2538
            $answerlist[$answer_ident] = array($feedback_ident, ($answer_grade_fraction > 0));
2539
        }
2540
 
2541
        $this->answerlist = $answerlist;
2542
 
2543
    }
2544
 
2545
    public function on_generate_feedbacks() {
2546
        parent::on_generate_feedbacks();
2547
        //Question combined feedbacks
2548
        $correct_question_fb = $this->questions->nodeValue('plugin_qtype_multichoice_question/multichoice/correctfeedback', $this->question_node);
2549
        $incorrect_question_fb = $this->questions->nodeValue('plugin_qtype_multichoice_question/multichoice/incorrectfeedback', $this->question_node);
2550
        if (empty($correct_question_fb)) {
2551
            //Hardcode some text for now
2552
            $correct_question_fb = 'Well done!';
2553
        }
2554
        if (empty($incorrect_question_fb)) {
2555
            //Hardcode some text for now
2556
            $incorrect_question_fb = 'Better luck next time!';
2557
        }
2558
 
2559
        $proc = array('correct_fb' => $correct_question_fb, 'incorrect_fb' => $incorrect_question_fb);
2560
        foreach ($proc as $ident => $content) {
2561
            if (empty($content)) {
2562
                continue;
2563
            }
2564
            $result = cc_helpers::process_linked_files( $content,
2565
                                                        $this->manifest,
2566
                                                        $this->rootpath,
2567
                                                        $this->contextid,
2568
                                                        $this->outdir);
2569
 
2570
            cc_assesment_helper::add_feedback( $this->qitem,
2571
                                                $result[0],
2572
                                                cc_qti_values::htmltype,
2573
                                                $ident);
2574
 
2575
            pkg_resource_dependencies::instance()->add($result[1]);
2576
            if ($ident == 'correct_fb') {
2577
                $this->correct_feedbacks[$ident] = $ident;
2578
            } else {
2579
                $this->incorrect_feedbacks[$ident] = $ident;
2580
            }
2581
        }
2582
 
2583
    }
2584
 
2585
    public function on_generate_response_processing() {
2586
        parent::on_generate_response_processing();
2587
 
2588
        //respconditions
2589
        /**
2590
        * General unconditional feedback must be added as a first respcondition
2591
        * without any condition and just displayfeedback (if exists)
2592
        */
2593
        cc_assesment_helper::add_respcondition( $this->qresprocessing,
2594
                                                'General feedback',
2595
                                                $this->general_feedback,
2596
                                                null,
2597
                                                true
2598
                                               );
2599
 
2600
        //success condition
2601
        /**
2602
        * For all question types outside of the Essay question, scoring is done in a
2603
        * single <respcondition> with a continue flag set to No. The outcome is always
2604
        * a variable named SCORE which value must be set to 100 in case of correct answer.
2605
        * Partial scores (not 0 or 100) are not supported.
2606
        */
2607
        $qrespcondition = new cc_assesment_respconditiontype();
2608
        $qrespcondition->set_title('Correct');
2609
        $this->qresprocessing->add_respcondition($qrespcondition);
2610
        $qrespcondition->enable_continue(false);
2611
        $qsetvar = new cc_assignment_setvartype(100);
2612
        $qrespcondition->add_setvar($qsetvar);
2613
        //define the condition for success
2614
        $qconditionvar = new cc_assignment_conditionvar();
2615
        $qrespcondition->set_conditionvar($qconditionvar);
2616
        //create root and condition
2617
        $qandcondition = new cc_assignment_conditionvar_andtype();
2618
        $qconditionvar->set_and($qandcondition);
2619
        foreach ($this->answerlist as $ident => $refid) {
2620
            $qvarequal = new cc_assignment_conditionvar_varequaltype($ident);
2621
            $qvarequal->enable_case();
2622
            if ($refid[1]) {
2623
                $qandcondition->set_varequal($qvarequal);
2624
            } else {
2625
                $qandcondition->set_not($qvarequal);
2626
            }
2627
            $qvarequal->set_respident($this->qresponse_lid->get_ident());
2628
        }
2629
 
2630
        $qdisplayfeedback = new cc_assignment_displayfeedbacktype();
2631
        $qrespcondition->add_displayfeedback($qdisplayfeedback);
2632
        $qdisplayfeedback->set_feedbacktype(cc_qti_values::Response);
2633
        //TODO: this needs to be fixed
2634
        reset($this->correct_feedbacks);
2635
        $ident = key($this->correct_feedbacks);
2636
        $qdisplayfeedback->set_linkrefid($ident);
2637
 
2638
 
2639
        //rest of the conditions
2640
        foreach ($this->answerlist as $ident => $refid) {
2641
            cc_assesment_helper::add_response_condition( $this->qresprocessing,
2642
                                                         'Incorrect feedback',
2643
                                                         $refid[0],
2644
                                                         $this->general_feedback,
2645
                                                         $this->qresponse_lid->get_ident()
2646
                                                       );
2647
        }
2648
 
2649
        //Final element for incorrect feedback
2650
        reset($this->incorrect_feedbacks);
2651
        $ident = key($this->incorrect_feedbacks);
2652
        cc_assesment_helper::add_respcondition( $this->qresprocessing,
2653
                                                'Incorrect feedback',
2654
                                                $ident,
2655
 
2656
                                              );
2657
 
2658
    }
2659
 
2660
}