18 require_once SQ_PACKAGES_PATH.
'/cms/page_templates/page_asset_listing/page_asset_listing.inc';
19 require_once SQ_LIB_PATH.
'/html_form/html_form.inc';
22 define(
'SQ_ONLINE_QUIZ_SESSION_VAR',
'SQ_ONLINE_QUIZ');
23 define(
'SQ_ONLINE_QUIZ_FLAG_COMPLETE',
'is_complete');
83 var $_error_stack = Array(
85 'warnings' => Array(),
99 parent::__construct($assetid);
101 $this->_bodycopies = Array(
102 'page_contents' => translate(
'cms_page_contents'),
103 'no_results' => translate(
'cms_page_contents_no_results'),
104 'thank_you' => translate(
'online_quiz_bodycopy_thank_you'),
105 'already_taken' => translate(
'online_quiz_bodycopy_already_taken'),
106 'user_details' => translate(
'online_quiz_bodycopy_user_details'),
121 $page_links = parent::_getAllowedLinks();
123 $page_links[SQ_LINK_TYPE_1][
'folder'] = Array(
'card' =>
'M');
124 $page_links[SQ_LINK_TYPE_1][
'online_quiz_question'] = Array(
'card' =>
'M');
125 $page_links[SQ_LINK_TYPE_1][
'online_quiz_question_group'] = Array(
'card' =>
'M');
126 $page_links[SQ_LINK_TYPE_2][
'bodycopy'] = Array(
'card' =>
'M');
127 $page_links[SQ_LINK_TYPE_3][
'bodycopy'] = Array(
'card' =>
'M');
128 $page_links[SQ_LINK_TYPE_2][
'simple_form'] = Array(
'card' =>
'M');
129 $page_links[SQ_LINK_TYPE_3][
'simple_form'] = Array(
'card' =>
'M');
130 $page_links[SQ_LINK_NOTICE][
'user'] = Array(
'card' =>
'M');
152 if (!parent::_createAdditional($link))
return FALSE;
174 $bodycopies = $this->_bodycopies;
177 unset($bodycopies[
'no_results']);
180 if ($this->
attr(
'after_submit_action') !=
'thank_you') {
181 unset($bodycopies[
'thank_you']);
183 if ($this->
attr(
'can_retake')) {
184 unset($bodycopies[
'already_taken']);
188 foreach ($bodycopies as $bodycopy_code => $bodycopy_name) {
212 if (!empty($existing))
return TRUE;
213 $GLOBALS[
'SQ_SYSTEM']->am->includeAsset(
'folder');
215 $folder->setAttrValue(
'name', translate(
'submissions'));
216 $folder_link = Array(
'asset' => &$this,
'link_type' => SQ_LINK_TYPE_2,
'value' =>
'submissions_folder',
'is_dependant' => 1,
'is_exclusive' => 1);
217 if (!$folder->create($folder_link)) {
218 trigger_localised_error(
'CMS0070', E_USER_WARNING);
219 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'ROLLBACK');
220 $GLOBALS[
'SQ_SYSTEM']->restoreDatabaseConnection();
225 if (!$GLOBALS[
'SQ_SYSTEM']->am->acquireLock($folder->id,
'permissions')) {
228 if (!$GLOBALS[
'SQ_SYSTEM']->am->setPermission($folder->id, $GLOBALS[
'SQ_SYSTEM']->am->getSystemAssetid(
'public_user'), SQ_PERMISSION_READ, 0, TRUE, TRUE)) {
231 $GLOBALS[
'SQ_SYSTEM']->am->releaseLock($folder->id,
'permissions');
259 $GLOBALS[
'SQ_SYSTEM']->changeDatabaseConnection(
'db2');
260 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'BEGIN');
261 $GLOBALS[
'SQ_SYSTEM']->am->includeAsset(
'online_quiz_submission');
266 if (is_null($submissions_folder)) {
267 trigger_localised_error(
'CMS0069', E_USER_WARNING);
271 $copy_link = Array(
'asset' => &$submissions_folder,
'link_type' => SQ_LINK_TYPE_3,
'is_dependant' => 0,
'is_exclusive' => 0);
273 $GLOBALS[
'SQ_SYSTEM']->setRunLevel(SQ_RUN_LEVEL_FORCED);
274 if (!$submission->create($copy_link)) {
275 $GLOBALS[
'SQ_SYSTEM']->restoreRunLevel();
276 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'ROLLBACK');
277 $GLOBALS[
'SQ_SYSTEM']->restoreDatabaseConnection();
280 $GLOBALS[
'SQ_SYSTEM']->restoreRunLevel();
281 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'COMMIT');
282 $GLOBALS[
'SQ_SYSTEM']->restoreDatabaseConnection();
298 $link = $GLOBALS[
'SQ_SYSTEM']->am->getLink($this->
id, SQ_LINK_TYPE_2,
'folder', TRUE,
'submissions_folder');
300 $res = $GLOBALS[
'SQ_SYSTEM']->am->getAsset($link[
'minorid'],
'folder');
319 switch ($bodycopy_code) {
321 case 'page_contents':
322 $content =
'%asset_listing% %submit_button%';
325 return '<p>'.translate(
'online_quiz_bodycopy_no_result_default').
'</p>';
328 $content =
'<p>'.translate(
'online_quiz_bodycopy_thank_you_default').
'</p>'.
"\n";
329 $content .=
'%results_table_full%';
332 $content =
'<p>'.translate(
'online_quiz_bodycopy_user_details_default').
'</p>'.
"\n";
333 $content .=
'%form_contents%';
335 case 'already_taken':
336 $content =
'<p>'.translate(
'online_quiz_bodycopy_already_taken_default').
'</p>';
340 case 'online_quiz_question':
341 $content .=
'<div>%question_text%</div>'.
"\n";
342 $content .=
'%response_form%';
347 $content = parent::_getDefaultBodycopyContent($bodycopy_code);
369 $bodycopy_link = $this->
getBodycopyLink($bodycopy_code, SQ_LINK_TYPE_2 | SQ_LINK_TYPE_3);
372 if ($bodycopy_link) {
375 $GLOBALS[
'SQ_SYSTEM']->am->includeAsset(
'bodycopy');
377 $link_type = ($enable_on_create ? SQ_LINK_TYPE_2 : SQ_LINK_TYPE_3);
382 'value' => $bodycopy_code,
383 'link_type' => $link_type,
388 $asset->setAttrValue(
'name', $this->_bodycopies[$bodycopy_code]);
393 if (!$asset->create($copy_link, $args))
return FALSE;
417 if ($only_if_enabled) {
418 $link_types = SQ_LINK_TYPE_2;
420 $link_types = SQ_LINK_TYPE_2 | SQ_LINK_TYPE_3;
424 if ($bodycopy_link) {
425 $asset = $GLOBALS[
'SQ_SYSTEM']->am->getAsset($bodycopy_link[
'minorid'],
'bodycopy');
444 $tmp_bodycopy = $GLOBALS[
'SQ_SYSTEM']->am->getLinks($this->
id, $link_type,
'bodycopy', FALSE,
'major', $bodycopy_code);
445 return reset($tmp_bodycopy);
461 $bodycopy_link = $this->
getBodycopyLink($bodycopy_code, SQ_LINK_TYPE_2 | SQ_LINK_TYPE_3);
463 if (!$bodycopy_link) {
473 $new_link_type = ($enabled) ? SQ_LINK_TYPE_2 : SQ_LINK_TYPE_3;
474 if ($bodycopy_link[
'link_type'] != $new_link_type) {
475 $GLOBALS[
'SQ_SYSTEM']->am->updateLink($bodycopy_link[
'linkid'], $new_link_type);
492 if ($this->
getFlag(SQ_ONLINE_QUIZ_FLAG_COMPLETE) && !$this->
attr(
'can_retake')) {
494 }
else if ($this->
attr(
'interactive_mode')){
515 $bodycopy_printed = FALSE;
518 if (!is_null($bodycopy)) {
520 require_once SQ_FUDGE_PATH.
'/general/text.inc';
521 $keywords = $bodycopy->getKeywords();
522 $replacements = Array();
523 foreach ($keywords as $keyword) {
526 $bodycopy->setKeywordReplacements($replacements);
528 $bodycopy->printBody();
529 $bodycopy_printed = TRUE;
532 return $bodycopy_printed;
551 if (!empty($form_link[
'minorid'])) {
552 $form = $GLOBALS[
'SQ_SYSTEM']->am->getAsset($form_link[
'minorid'],
'simple_form');
570 $tmp_form = $GLOBALS[
'SQ_SYSTEM']->am->getLinks($this->
id, $link_type,
'simple_form', FALSE,
'major',
'user_details');
571 return reset($tmp_form);
586 $form_link = $this->
getFormLink(SQ_LINK_TYPE_2 | SQ_LINK_TYPE_3);
587 if (empty($form_link)) {
588 $GLOBALS[
'SQ_SYSTEM']->am->includeAsset(
'simple_form');
590 $form->setAttrValue(
'name', translate(
'online_quiz_form_user_details'));
593 'link_type' => $link_type,
594 'value' =>
'user_details',
598 if (!$form->create($link))
return FALSE;
616 $form_link = $this->
getFormLink(SQ_LINK_TYPE_2 | SQ_LINK_TYPE_3);
618 if (empty($form_link)) {
626 $new_link_type = ($enabled) ? SQ_LINK_TYPE_2 : SQ_LINK_TYPE_3;
627 if ($form_link[
'link_type'] != $new_link_type) {
628 return $GLOBALS[
'SQ_SYSTEM']->am->updateLink($form_link[
'linkid'], $new_link_type);
646 if (!is_null($form)) {
648 $form->printBody(TRUE, TRUE, $_SERVER[
'PHP_SELF'].
'?'.$this->
id.
'_formid='.$form->id);
649 $GLOBALS[
'SQ_SYSTEM']->am->forgetAsset($form);
650 return ob_get_clean();
666 if (!empty($this->_tmp[
'form_errors'])) {
669 foreach ($this->_tmp[
'form_errors'] as $error) {
675 return ob_get_clean();
697 $folder = $this->
getFolder(
'type_formats');
698 $types = $edit_fns->_getAvailableTypes($this);
701 if ($new_type !=
'' && !isset($types[$new_type])) {
702 trigger_localised_error(
'CMS0045', E_USER_WARNING, $new_type);
707 $current_link = $GLOBALS[
'SQ_SYSTEM']->am->getLink($folder->id, SQ_LINK_TYPE_2,
'bodycopy', TRUE, $new_type);
708 if (empty($current_link)) {
710 $GLOBALS[
'SQ_SYSTEM']->changeDatabaseConnection(
'db2');
711 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'BEGIN');
712 $GLOBALS[
'SQ_SYSTEM']->am->includeAsset(
'bodycopy');
716 'value' => $new_type,
717 'link_type' => SQ_LINK_TYPE_2,
723 $bodycopy->setAttrValue(
'name', $GLOBALS[
'SQ_SYSTEM']->am->getTypeInfo($new_type,
'name').
' Format');
725 if (!$bodycopy->create($copy_link, $args)) {
726 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'ROLLBACK');
727 $GLOBALS[
'SQ_SYSTEM']->restoreDatabaseConnection();
730 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'COMMIT');
731 $GLOBALS[
'SQ_SYSTEM']->restoreDatabaseConnection();
733 trigger_localised_error(
'CMS0046', E_USER_WARNING, $new_type);
753 $base_url = ($this->
attr(
'submit_to_page_url') ? $this->
getURL() : current_url());
756 $replacements = Array(
757 $this->
id.
'_formid' => NULL,
760 if ($form_method ==
'get') {
765 $url = replace_query_string_vars($replacements, $base_url);
770 'url_base' => $base_url,
787 $GLOBALS[
'SQ_SYSTEM']->changeDatabaseConnection(
'db2');
789 $can_take_quiz = TRUE;
790 if ($this->
getFlag(SQ_ONLINE_QUIZ_FLAG_COMPLETE)) {
791 if (!$this->
attr(
'can_retake')) {
792 $can_take_quiz = FALSE;
796 if ($can_take_quiz) {
797 if ($this->
attr(
'interactive_mode')){
804 parent::printFrontend();
805 $GLOBALS[
'SQ_SYSTEM']->restoreDatabaseConnection();
822 $flag_complete = $this->
getFlag(SQ_ONLINE_QUIZ_FLAG_COMPLETE);
825 if (isset($_REQUEST[$this->
getPrefix().
'_submit_button']) && !$flag_complete) {
829 'questions' => Array(),
832 'available_points' => 0,
835 foreach ($questions as $id => $details) {
836 $question = $GLOBALS[
'SQ_SYSTEM']->am->getAsset($id);
837 if (!is_null($question)) {
838 $question_results = $question->getResults();
840 $points = $question->getPoints();
841 $available = $question->getAvailablePoints();
842 $position = $question->getPosition();
844 $results[
'questions'][$position] = $question_results;
845 $results[
'totals'][
'points'] += $points;
846 $results[
'totals'][
'available_points'] += $available;
848 $GLOBALS[
'SQ_SYSTEM']->am->forgetAsset($question);
853 ksort($results[
'questions'], SORT_NUMERIC);
855 if ($this->
attr(
'interactive_mode')){
857 foreach (array_keys($results[
'questions']) as $position){
858 if (strpos($position,
' retry ') !== FALSE){
859 $components = explode(
' retry ', $position);
860 if ($components[1] > 1){
861 $previous_position = $components[0].
' retry '.--$components[1];
863 $previous_position = $components[0];
866 if (isset($results[
'questions'][$previous_position])){
867 $results[
'totals'][
'points'] -= $results[
'questions'][$previous_position][
'points'];
868 $results[
'questions'][$previous_position][
'points'] = 0;
869 $results[
'totals'][
'available_points'] -= $results[
'questions'][$previous_position][
'available_points'];
870 $results[
'questions'][$previous_position][
'available_points'] = 0;
874 ksort($results[
'questions'], SORT_STRING);
881 if ($this->
attr(
'log_submissions')) {
884 $user_details_form = $this->
getForm();
885 $user_details_form_questions = $user_details_form->getQuestions();
889 $question_results = $quiz_results[
'questions'];
892 foreach ($user_details as $question_id => $user_response) {
893 $question_asset = $GLOBALS[
'SQ_SYSTEM']->am->getAsset($question_id);
894 $submission_asset->setUserDetailsQuestion($question_id, $question_asset->getVal(
'title'));
895 $submission_asset->setUserDetailsAnswer($question_id, $user_response);
896 $GLOBALS[
'SQ_SYSTEM']->am->forgetAsset($question_asset);
899 foreach ($question_results as $question_position => $question_result) {
900 $question_asset = $GLOBALS[
'SQ_SYSTEM']->am->getAsset($question_result[
'assetid']);
902 $question_text = strip_tags($question_asset->getQuestionText());
903 $question_result[
'correct_summary'] = trim(strip_tags($question_result[
'correct_summary']));
904 $question_result[
'summary'] = trim(strip_tags($question_result[
'summary']));
906 $submission_asset->setQuizQuestion($question_result[
'assetid'], trim($question_text));
907 $submission_asset->setQuizAnswer($question_result[
'assetid'], $question_result);
908 $GLOBALS[
'SQ_SYSTEM']->am->forgetAsset($question_asset);
912 $submission_asset->setIP($_SERVER[
'REMOTE_ADDR']);
913 $submission_asset->setAttrValue(
'complete', TRUE);
914 $submission_asset->saveAttributes();
921 switch ($this->
attr(
'after_submit_action')) {
927 $this->
setFlag(SQ_ONLINE_QUIZ_FLAG_COMPLETE, TRUE, TRUE);
931 case 'return_to_quiz':
934 $this->
setFlag(SQ_ONLINE_QUIZ_FLAG_COMPLETE, TRUE, TRUE);
946 if (!$this->
attr(
'can_retake')) {
958 if ($flag_complete) {
959 $this->
setFlag(SQ_ONLINE_QUIZ_FLAG_COMPLETE, FALSE, TRUE);
962 if ($this->
attr(
'interactive_mode')){
964 if (empty($question_pagination[
'pages_to_questions'])){
970 $form_url = htmlspecialchars($form_url_components[
'url']);
971 ?> <form
id=
"<?php echo $this->getPrefix() ?>" method=
"<?php echo $form_method ?>" action=
"<?php echo $form_url; ?>"> <?php
983 hidden_field(
'quiz_'.$this->
id.
'_old_result_page', $this->
getCurrentPage());
987 hidden_field(
'quiz_'.$this->
id.
'_result_page',
'');
990 $_REQUEST[
'result_'.$this->id.
'_result_page'] = $this->
getCurrentPage();
993 $page_contents_link = $GLOBALS[
'SQ_SYSTEM']->am->getLink($this->
id, SQ_LINK_TYPE_2,
'bodycopy', TRUE,
'page_contents');
994 if (!empty($page_contents_link)) {
995 $format_bodycopy = $GLOBALS[
'SQ_SYSTEM']->am->getAsset($page_contents_link[
'minorid'], $page_contents_link[
'minor_type_code']);
997 require_once SQ_FUDGE_PATH.
'/general/text.inc';
998 $keywords = $format_bodycopy->getKeywords();
1000 if (!in_array(
'asset_listing', $keywords)) {
1001 $replacements = Array();
1002 foreach ($keywords as $word) {
1006 $format_bodycopy->setKeywordReplacements($replacements);
1008 $GLOBALS[
'SQ_SYSTEM']->am->forgetAsset($format_bodycopy);
1012 parent::printContents();
1036 $assets_to_list = Array();
1039 if (!empty($questions)) {
1040 foreach ($questions as $id => $details) {
1042 if ($this->
attr(
'group_by') ==
'letter') {
1043 $assets_to_list[$id] = $details;
1045 $assets_to_list[$id] = Array( 0 => Array(
'type_code' => $details[
'type_code']));
1050 return $assets_to_list;
1075 if ($this->
attr(
'interactive_mode')){
1076 if ($all_interactive){
1082 $interactive_questions = $question_pagination[
'questions_to_pages'];
1091 if ($refresh === TRUE) {
1092 $questions = Array();
1098 if (empty($questions) && $refresh !== FALSE) {
1101 $manually_configured_questions = !empty($assets_to_list);
1103 if (empty($assets_to_list)) {
1104 $assets_to_list = parent::getAssetList();
1105 parent::filterAssetTypes($assets_to_list);
1108 if (empty($assets_to_list))
return Array();
1111 $attr_num_questions = $this->
attr(
'num_questions');
1112 if ($attr_num_questions <= 0 || $attr_num_questions > count($assets_to_list)) {
1113 $num_questions = count($assets_to_list);
1115 $num_questions = $attr_num_questions;
1119 if ($manually_configured_questions) {
1120 $random_asset_list =& $assets_to_list;
1124 $random_asset_list = Array();
1129 $mandatory_listing_assets = $this->
attr(
'asset_positions');
1130 foreach ($mandatory_listing_assets as $index => $info) {
1131 if (isset($assets_to_list[$info[
'id']])) unset ($assets_to_list[$info[
'id']]);
1134 $num_questions = $num_questions - count($mandatory_listing_assets);
1136 $random_asset_list_keys = array_rand($assets_to_list, $num_questions);
1137 if ($num_questions == 1) {
1138 $random_asset_list_keys = Array($random_asset_list_keys);
1141 foreach($mandatory_listing_assets as $index => $info) {
1142 $random_asset_list[$info[
'id']] = Array (
'0' => Array (
'type_code' => $info[
'type'] ));
1145 foreach ($random_asset_list_keys as $key) {
1146 $random_asset_list[$key] = $assets_to_list[$key];
1151 foreach ($random_asset_list as $assetid => $type) {
1155 if ($this->
attr(
'group_by') ==
'letter') {
1156 $questions[$assetid] = $type;
1157 $questions[$assetid][
'value'] = NULL;
1158 $questions[$assetid][
'position'] = NULL;
1160 $questions[$assetid] = Array(
1161 'type_code' => $type,
1176 $existing_questions = array_flip($GLOBALS[
'SQ_SYSTEM']->am->assetExists(array_keys($questions)));
1177 foreach ($questions as $id => $question) {
1178 if (!isset($existing_questions[$id])) {
1179 unset($questions[$id]);
1198 require_once SQ_FUDGE_PATH.
'/general/general.inc';
1200 $interactive_questions = Array ();
1202 $pool_links = $GLOBALS[
'SQ_SYSTEM']->am->getLinks($this->
id, SQ_LINK_NOTICE,
'', FALSE,
'major',
'root');
1203 foreach ($pool_links as $link){
1204 $questions = $GLOBALS[
'SQ_SYSTEM']->am->getChildren($link[
'minorid'],
'online_quiz_question_multichoice', TRUE, NULL, NULL, SQ_PERMISSION_READ);
1205 if (!empty($questions)){
1206 $questions = dal_array_flatten($questions);
1209 foreach ($questions as $question_id => $type_code){
1210 $question = $GLOBALS[
'SQ_SYSTEM']->am->getAsset($question_id);
1211 if (is_null($question) || !$question->readAccess()) {
1212 unset($questions[$question_id]);
1217 $keys = array_rand($questions, count($questions));
1218 if (!is_array($keys)) $keys = Array($keys);
1219 $randomised_questions = Array();
1220 foreach ($keys as $key){
1221 $randomised_questions[$key] = $questions[$key];
1225 $interactive_questions[$link[
'minorid']] = $randomised_questions;
1227 $interactive_questions += $randomised_questions;
1232 return $interactive_questions;
1246 $assets_to_list = Array();
1248 $page_contents_link = $GLOBALS[
'SQ_SYSTEM']->am->getLink($this->
id, SQ_LINK_TYPE_2,
'bodycopy', TRUE,
'page_contents');
1249 if (!empty($page_contents_link)) {
1250 $format_bodycopy = $GLOBALS[
'SQ_SYSTEM']->am->getAsset($page_contents_link[
'minorid'], $page_contents_link[
'minor_type_code']);
1251 require_once SQ_FUDGE_PATH.
'/general/text.inc';
1252 $keywords = $format_bodycopy->getKeywords();
1253 $GLOBALS[
'SQ_SYSTEM']->am->forgetAsset($format_bodycopy);
1257 if (!in_array(
'asset_listing', $keywords)) {
1258 $replacements = Array();
1259 foreach ($keywords as $keyword) {
1260 if (preg_match(
'/^(question)_([0-9]*)_(response_form)$/', $keyword, $matches)) {
1261 if (isset($matches[1]) && isset($matches[2]) && isset($matches[3])) {
1263 $question_asset_id = $matches[2];
1264 $question = $GLOBALS[
'SQ_SYSTEM']->am->getAsset($question_asset_id);
1267 $question_type = $question->type();
1268 if ($question_type ==
'online_quiz_question_multichoice') {
1269 if (isset($matches[1]) && isset($matches[2])) {
1271 if ($question->readAccess()) {
1272 $assets_to_list[$question_asset_id] = $question_type;
1277 $GLOBALS[
'SQ_SYSTEM']->am->forgetAsset($question);
1284 return $assets_to_list;
1297 $email_attr = $this->
getAttribute(
'results_email_format');
1298 $value = unserialize($email_attr->value);
1301 $value[
'text_format'] = str_replace(
'%results_table_full%',
'%results_table_full_text%', $value[
'text_format']);
1302 $value[
'text_format'] = str_replace(
'%results_table_simple%',
'%results_table_simple_text%', $value[
'text_format']);
1305 $result_keywords = Array(
1306 'question_text',
'answer_text',
'correct_answer_text',
'question_note',
1308 foreach ($result_keywords as $result_keyword) {
1309 $value[
'text_format'] = preg_replace(
'/%(result)_([0-9]*)_('.$result_keyword.
')%/',
'%result_$2_$3_plain%', $value[
'text_format']);
1311 $value[
'text_format'] = preg_replace(
'/%(result)_([0-9]*)_(response_supplement)%/',
'%result_$2_$3_text%', $value[
'text_format']);
1312 $value[
'text_format'] = preg_replace(
'/%(question_group)_([0-9]*)_(score_category_supplement)%/',
'%question_group_$2_$3_text%', $value[
'text_format']);
1314 $email_attr->value = serialize($value);
1316 $keywords = $email_attr->getKeywords();
1318 $replacements = Array();
1319 foreach ($keywords as $keyword) {
1324 return $email_attr->sendMail($replacements);
1339 if (is_null($questions)) {
1343 if (is_array($questions)) {
1344 foreach ($questions as $assetid) {
1345 unset($_SESSION[SQ_ONLINE_QUIZ_SESSION_VAR][
'question'][$assetid]);
1350 unset($_SESSION[SQ_ONLINE_QUIZ_SESSION_VAR][
'quiz'][$this->
id]);
1364 if (!empty($_SESSION[SQ_ONLINE_QUIZ_SESSION_VAR][
'quiz'][$this->
id][
'user_details'])) {
1365 $details = $_SESSION[SQ_ONLINE_QUIZ_SESSION_VAR][
'quiz'][$this->id][
'user_details'];
1383 if (is_array($details)) {
1384 $_SESSION[SQ_ONLINE_QUIZ_SESSION_VAR][
'quiz'][$this->id][
'user_details'] = $details;
1410 if ($this->
attr(
'user_details_source') ==
'form' || $GLOBALS[
'SQ_SYSTEM']->userPublic()) {
1412 if (empty($user_details)) {
1416 if (!is_null($form)) {
1418 if (array_get_index($_REQUEST, $this->
id.
'_formid') && $form->process()) {
1423 $this->_tmp[
'form_errors'] = $form->getErrors();
1427 $GLOBALS[
'SQ_SYSTEM']->am->forgetAsset($form);
1450 if (!$GLOBALS[
'SQ_SYSTEM']->userPublic()) {
1451 $link = $GLOBALS[
'SQ_SYSTEM']->am->getLinkByAsset($this->
id, $GLOBALS[
'SQ_SYSTEM']->user->id, SQ_LINK_NOTICE);
1452 if (!empty($link)) {
1453 $link_value = unserialize($link[
'value']);
1454 $return = array_get_index($link_value, $flag, NULL);
1459 if (is_null($return)) {
1460 if (isset($_SESSION[SQ_ONLINE_QUIZ_SESSION_VAR][
'quiz'][$this->
id][
'flags'][$flag])) {
1461 $return = $_SESSION[SQ_ONLINE_QUIZ_SESSION_VAR][
'quiz'][$this->id][
'flags'][$flag];
1482 if (empty($flag))
return FALSE;
1486 if ($permanent && !$GLOBALS[
'SQ_SYSTEM']->userPublic()) {
1488 $GLOBALS[
'SQ_SYSTEM']->setRunLevel(SQ_RUN_LEVEL_FORCED);
1490 $link = $GLOBALS[
'SQ_SYSTEM']->am->getLinkByAsset($this->
id, $GLOBALS[
'SQ_SYSTEM']->user->id, SQ_LINK_NOTICE);
1491 if (!empty($link)) {
1493 $link_value = unserialize($link[
'value']);
1494 $link_value[$flag] = $value;
1495 $new_link_value = serialize($link_value);
1496 $res = $GLOBALS[
'SQ_SYSTEM']->am->updateLink($link[
'linkid'], SQ_LINK_NOTICE, $new_link_value);
1501 $new_link_value = serialize($new_value);
1502 $res = $GLOBALS[
'SQ_SYSTEM']->am->createAssetLink($this, $GLOBALS[
'SQ_SYSTEM']->user, SQ_LINK_NOTICE, $new_link_value);
1505 $GLOBALS[
'SQ_SYSTEM']->restoreRunLevel();
1511 $_SESSION[SQ_ONLINE_QUIZ_SESSION_VAR][
'quiz'][$this->id][
'flags'][$flag] = $value;
1544 if (!empty($_SESSION[SQ_ONLINE_QUIZ_SESSION_VAR][
'quiz'][$this->
id][
'results'])) {
1545 $results = $_SESSION[SQ_ONLINE_QUIZ_SESSION_VAR][
'quiz'][$this->id][
'results'];
1564 $_SESSION[SQ_ONLINE_QUIZ_SESSION_VAR][
'quiz'][$this->id][
'results'] = $results;
1578 $questions = Array();
1582 if (!empty($question_list)) {
1583 foreach ($question_list as $assetid) {
1585 if (!empty($_SESSION[SQ_ONLINE_QUIZ_SESSION_VAR][
'question'][$assetid])) {
1586 $questions[$assetid] = $_SESSION[SQ_ONLINE_QUIZ_SESSION_VAR][
'question'][$assetid];
1588 $question = $GLOBALS[
'SQ_SYSTEM']->am->getAsset($assetid);
1589 if (!is_null($question)) {
1590 $questions[$assetid] = $question->getQuestionData();
1591 $GLOBALS[
'SQ_SYSTEM']->am->forgetAsset($question);
1612 if (!empty($questions)) {
1613 foreach ($questions as $assetid => $question_data) {
1614 $question = $GLOBALS[
'SQ_SYSTEM']->am->getAsset($assetid);
1615 if (!is_null($question)) {
1616 $questions[$assetid] = $question->setValue($question_data[
'value']);
1617 $questions[$assetid] = $question->setPosition($question_data[
'position']);
1618 $question->saveQuestion();
1619 $GLOBALS[
'SQ_SYSTEM']->am->forgetAsset($question);
1635 $question_list = Array();
1638 if (!empty($_SESSION[SQ_ONLINE_QUIZ_SESSION_VAR][
'quiz'][$this->
id][
'question_list'])) {
1639 $question_list = $_SESSION[SQ_ONLINE_QUIZ_SESSION_VAR][
'quiz'][$this->id][
'question_list'];
1642 return $question_list;
1657 if (!is_array($question_list)) {
1658 $question_list = Array();
1662 $_SESSION[SQ_ONLINE_QUIZ_SESSION_VAR][
'quiz'][$this->id][
'question_list'] = $question_list;
1678 $question_pagination = Array();
1679 if (!empty($_SESSION[SQ_ONLINE_QUIZ_SESSION_VAR][
'quiz'][$this->
id][
'question_pagination'])) {
1680 $question_pagination = $_SESSION[SQ_ONLINE_QUIZ_SESSION_VAR][
'quiz'][$this->id][
'question_pagination'];
1683 if (empty($question_pagination) || empty($question_pagination[
'pages_to_questions'])) {
1685 if ($this->
attr(
'interactive_mode')){
1700 $pool_setup = $this->
attr(
'question_pool_setup');
1703 foreach ($pool_setup as $pool_id => $info){
1704 if (isset($question_pool[$pool_id])){
1705 $questions = $question_pool[$pool_id];
1710 for ($size = 0; $size < $info[
'size']; $size++){
1712 $question_id = key($questions);
1713 if (empty($question_id)) {
1714 trigger_localised_error(
'CMS0112', E_USER_WARNING, $pool_id);
1717 $question_pagination[
'pages_to_questions'][$page_no][$question_id] = $questions[$question_id][
'type_code'];
1718 $question_pagination[
'questions_to_pages'][$question_id] = Array(
1720 'list_position' => $page_no
1722 $question_pagination[
'pages_to_status'][$page_no] =
'submit_question';
1723 unset($questions[$question_id]);
1726 for ($retries = 0; $retries < $info[
'retries']; $retries++){
1728 $question_id = key($questions);
1729 if (empty($question_id)) {
1730 trigger_localised_error(
'CMS0112', E_USER_WARNING, $pool_id);
1733 $question_pagination[
'pages_to_retry_questions'][$page_no][$question_id] = $questions[$question_id][
'type_code'];
1734 unset($questions[$question_id]);
1744 $replacements = Array();
1745 $question_pagination = Array(
1746 'pages_to_questions' => Array(),
1747 'questions_to_pages' => Array(),
1760 require_once SQ_FUDGE_PATH.
'/general/general.inc';
1761 $current_page_assets = dal_array_flatten($this->
getPageAssets($children, $replacements, $current_result_page),
'type_code');
1762 $total_pages = $replacements[
'total_pages'];
1764 if (!empty($current_page_assets)) {
1765 $question_pagination[
'pages_to_questions'][$current_result_page] = $current_page_assets;
1768 for ($ii = 1; $ii <= $total_pages; $ii++) {
1769 if (isset($question_pagination[
'pages_to_questions'][$ii])) {
1770 $page_assets = $question_pagination[
'pages_to_questions'][$ii];
1772 $page_assets = dal_array_flatten($this->
getPageAssets($children, $replacements, $ii),
'type_code');
1773 $question_pagination[
'pages_to_questions'][$ii] = $page_assets;
1778 foreach ($page_assets as $assetid => $type) {
1779 $question_pagination[
'questions_to_pages'][$assetid] = Array(
1781 'list_position' => ($ii - 1) * $num_per_page + $asset_count,
1793 return $question_pagination;
1810 $_SESSION[SQ_ONLINE_QUIZ_SESSION_VAR][
'quiz'][$this->id][
'question_pagination'] = $question_pagination;
1829 if (empty($question_pagination[
'pages_to_questions']))
return TRUE;
1833 $current_question_id = key($question_pagination[
'pages_to_questions'][$current_result_page]);
1835 $current_status = $question_pagination[
'pages_to_status'][$current_result_page];
1839 if (isset($_POST[$prefix.
'_submit_next_button']) && $current_status ==
'feedback_next'){
1840 $_SESSION[SQ_ONLINE_QUIZ_SESSION_VAR][
'quiz'][$this->id][
'interactive_page'] = $current_result_page + 1;
1841 $question_pagination[
'pages_to_status'][$current_result_page] =
'answered';
1842 }
else if (isset($_POST[$prefix.
'_submit_retry_button']) && $current_status ==
'feedback_retry'){
1844 if (!empty($question_pagination[
'pages_to_retry_questions'][$current_result_page])) {
1846 $question_id = key($question_pagination[
'pages_to_retry_questions'][$current_result_page]);
1847 $question_type = $question_pagination[
'pages_to_retry_questions'][$current_result_page][$question_id];
1848 unset($question_pagination[
'pages_to_retry_questions'][$current_result_page][$question_id]);
1849 $question_pagination[
'pages_to_questions'][$current_result_page] = Array ($question_id => $question_type);
1852 $question_pagination[
'questions_to_pages'][$question_id] = $question_pagination[
'questions_to_pages'][$current_question_id];
1853 $question_list_position = $question_pagination[
'questions_to_pages'][$question_id][
'list_position'];
1854 if (strpos($question_list_position,
' retry ') !== FALSE){
1855 $components = explode(
' retry ', $question_list_position);
1856 $question_list_position = $components[0].
' retry '.++$components[1];
1858 $question_list_position .=
' retry 1';
1860 $question_pagination[
'questions_to_pages'][$question_id][
'list_position'] = $question_list_position;
1863 $question_pagination[
'pages_to_status'][$current_result_page] =
'submit_question_retry';
1865 $question_pagination[
'pages_to_status'][$current_result_page] =
'feedback_next';
1867 }
else if (isset($_POST[$prefix.
'_submit_question_button']) && strpos($current_status,
'submit_question') === 0){
1868 $question = $GLOBALS[
'SQ_SYSTEM']->am->getAsset($current_question_id);
1869 if (!is_null($question)) {
1870 if ($current_status ==
'submit_question_retry'){
1871 if (isset($_SESSION[SQ_ONLINE_QUIZ_SESSION_VAR][
'quiz'][$this->
id][
'interactive_score'][
'retries'])){
1872 $_SESSION[SQ_ONLINE_QUIZ_SESSION_VAR][
'quiz'][$this->id][
'interactive_score'][
'retries']++;
1874 $_SESSION[SQ_ONLINE_QUIZ_SESSION_VAR][
'quiz'][$this->id][
'interactive_score'][
'retries'] = 1;
1877 if (isset($_SESSION[SQ_ONLINE_QUIZ_SESSION_VAR][
'quiz'][$this->
id][
'interactive_score'][
'total_questions'])){
1878 $_SESSION[SQ_ONLINE_QUIZ_SESSION_VAR][
'quiz'][$this->id][
'interactive_score'][
'total_questions']++;
1880 $_SESSION[SQ_ONLINE_QUIZ_SESSION_VAR][
'quiz'][$this->id][
'interactive_score'][
'total_questions'] = 1;
1884 $errors = $question->processResponseForm();
1885 if ($current_result_page == count($question_pagination[
'pages_to_questions'])) {
1886 $question_pagination[
'pages_to_status'][$current_result_page] =
'feedback_last';
1888 $question_pagination[
'pages_to_status'][$current_result_page] =
'feedback_next';
1891 $value = $question->getValue();
1892 if (!is_array($value)) $value = Array($value);
1893 if (array_intersect($value, $question->getCorrectValue()) === Array()){
1894 if(!empty($question_pagination[
'pages_to_retry_questions'][$current_result_page])){
1895 $question_pagination[
'pages_to_status'][$current_result_page] =
'feedback_retry';
1898 if (isset($_SESSION[SQ_ONLINE_QUIZ_SESSION_VAR][
'quiz'][$this->
id][
'interactive_score'][
'correct_answers'])){
1899 $_SESSION[SQ_ONLINE_QUIZ_SESSION_VAR][
'quiz'][$this->id][
'interactive_score'][
'correct_answers']++;
1901 $_SESSION[SQ_ONLINE_QUIZ_SESSION_VAR][
'quiz'][$this->id][
'interactive_score'][
'correct_answers'] = 1;
1912 $current_question_id = key($question_pagination[
'pages_to_questions'][$current_result_page]);
1914 if (!empty($question_pagination[
'questions_to_pages'][$current_question_id][
'list_position'])) {
1915 $question = $GLOBALS[
'SQ_SYSTEM']->am->getAsset($current_question_id);
1916 if (!is_null($question)) {
1918 $question->setPosition($question_pagination[
'questions_to_pages'][$current_question_id][
'list_position']);
1919 $question->saveQuestion();
1945 $error_stack = Array(
1946 'errors' => Array(),
1947 'warnings' => Array(),
1955 $current_page_assets =& $question_pagination[
'pages_to_questions'][$current_result_page];
1958 $previous_page_assets = Array();
1959 $old_result_page = array_get_index($_REQUEST,
'quiz_'.$this->
id.
'_old_result_page', NULL);
1960 if (!is_null($old_result_page)) {
1961 $previous_page_assets =& $question_pagination[
'pages_to_questions'][$old_result_page];
1964 foreach ($questions as $questionid => $question_details) {
1965 $question = $GLOBALS[
'SQ_SYSTEM']->am->getAsset($questionid);
1966 if (!is_null($question)) {
1968 if (!empty($question_pagination[
'questions_to_pages'][$questionid][
'list_position'])) {
1969 $question->setPosition($question_pagination[
'questions_to_pages'][$questionid][
'list_position']);
1973 if (isset($previous_page_assets[$questionid])) {
1975 $errors = $question->processResponseForm();
1978 $errors = $question->validateValue();
1983 if (!isset($current_page_assets[$questionid]) || !$this->
attr(
'clientside_validation')) {
1984 if (!empty($errors[
'errors'])) {
1985 $error_stack[
'errors'] = array_merge($error_stack[
'errors'], $errors[
'errors']);
1987 if (!empty($errors[
'warnings'])) {
1988 $error_stack[
'warnings'] = array_merge($error_stack[
'warnings'], $errors[
'warnings']);
1992 $GLOBALS[
'SQ_SYSTEM']->am->forgetAsset($question);
1997 $this->_error_stack = $error_stack;
2022 function &
getChunk(&$children, &$replacements, $keywords, $result_page, $num_per_page, $group_by=NULL)
2024 $todo =& parent::getChunk($children, $replacements, $keywords, $result_page, $num_per_page, $group_by);
2033 $link_js =
' onClick="document.getElementById(\'quiz_'.$this->id.
'_result_page\').value=\'%s\'; '
2034 .
'frm=document.getElementById(\''.$this->
getPrefix().
'\');
'
2035 .'frm.action=\
''.htmlentities(replace_query_string_vars(Array(
'quiz_'.$this->
id.
'_result_page' => NULL))).
'\';
'
2036 .'frm.submit();
return false;
" ';
2038 // we have the luxury of assuming that #_result_page will always exist if a link is present
2039 $link_regex = '|(<a href=")(([^
"]*result_'.$this->id.'_result_page=)([[:alnum:]]*))([^"]*
")(>[^<]*</a>)|';
2042 $this->id.'_formid' => NULL,
2045 // next_page keyword
2046 preg_match($link_regex, $replacements['next_page'], $matches);
2047 if (!empty($matches)) {
2048 // remove the formid query var
2049 list($base, $query) = explode('?', $matches[2]);
2050 $url = replace_query_string_vars($url_reps, $base, $query);
2052 // sub the destination page into the javascript
2053 $dest_page = $matches[4];
2054 $replacements['next_page'] = $matches[1].htmlentities($url).$matches[5].sprintf($link_js, $dest_page).$matches[6];
2057 // previous_page keyword
2058 preg_match($link_regex, $replacements['previous_page'], $matches);
2059 if (!empty($matches)) {
2060 // remove the formid query var
2061 list($base, $query) = explode('?', $matches[2]);
2062 $url = replace_query_string_vars($url_reps, $base, $query);
2064 // sub the destination page into the javascript
2065 $dest_page = $matches[4];
2066 $replacements['previous_page'] = $matches[1].htmlentities($url).$matches[5].sprintf($link_js, $dest_page).$matches[6];
2070 // page_list keywords
2071 // do some trickery with the keyword replacements - replace %d in $link_js with a regex special character,
2072 // to get preg_replace to sub in the target page number for us
2073 $replacements['page_list'] = preg_replace(
2074 '|(<a href="[^
"]*result_'.$this->id.'_result_page=)([[:alnum:]]*)([^"]*
")([^>]*>)|',
2075 '$1$2$3'.sprintf($link_js, '$2').'$4',
2076 $replacements['page_list']
2078 $replacements['page_list_without_unused'] = preg_replace(
2079 '|(<a href="[^
"]*result_'.$this->id.'_result_page=)([[:alnum:]]*)([^"]*
")([^>]*>)|',
2080 '$1$2$3'.sprintf($link_js, '$2').'$4',
2081 $replacements['page_list']
2085 // unset the next_page_href and previous_page_href for safety (allows for the form
2086 // to change pages without submitting the form to save the questions)
2087 unset($replacements['next_page_href']);
2088 unset($replacements['previous_page_href']);
2095 //-- Keyword Listings --//
2107 function onRequestKeywords(&$broadcaster, $vars=Array())
2109 if (!isset($vars['keywords'])) return;
2110 if (!($broadcaster instanceof Content_Type)) return;
2112 $parents = $GLOBALS['SQ_SYSTEM']->am->getParents($broadcaster->id, 'bodycopy', TRUE);
2114 // the broadcaster could be our page contents bodycopy, in which case
2115 // we want to supply our own keyword replacements
2116 $page_contents_link = $GLOBALS['SQ_SYSTEM']->am->getLink($this->id, SQ_LINK_TYPE_2, 'bodycopy', TRUE, 'page_contents');
2117 if (!empty($page_contents_link)) {
2118 if (isset($parents[$page_contents_link['minorid']])) {
2119 $vars['keywords'] += $this->_getContentsKeywords();
2120 $vars['keywords'] += $this->_getQuestionKeywords();
2121 if ($this->attr('interactive_mode')){
2122 $vars['keywords'] += $this->_getInteractiveKeywords();
2128 // and the same for the thank_you page
2129 $thank_you_link = $GLOBALS['SQ_SYSTEM']->am->getLink($this->id, SQ_LINK_TYPE_2, 'bodycopy', TRUE, 'thank_you');
2130 if (!empty($thank_you_link)) {
2131 if (isset($parents[$thank_you_link['minorid']])) {
2132 $vars['keywords'] += $this->_getResultsKeywords();
2133 $vars['keywords'] += $this->_getUserDetailsKeywords();
2134 $vars['keywords'] += $this->_getQuestionResultKeywords();
2135 $vars['keywords'] += $this->_getQuestionGroupResultKeywords();
2136 $vars['keywords'] += Array ('quiz_score' => translate('online_quiz_keyword_quiz_score'));
2141 // and for the user_details page
2142 $user_details_link = $GLOBALS['SQ_SYSTEM']->am->getLink($this->id, SQ_LINK_TYPE_2, 'bodycopy', TRUE, 'user_details');
2143 if (!empty($user_details_link)) {
2144 if (isset($parents[$user_details_link['minorid']])) {
2145 $vars['keywords'] += $this->_getFormKeywords();
2151 // and the already_taken page
2152 $user_details_link = $GLOBALS['SQ_SYSTEM']->am->getLink($this->id, SQ_LINK_TYPE_2, 'bodycopy', TRUE, 'already_taken');
2153 if (!empty($user_details_link)) {
2154 if (isset($parents[$user_details_link['minorid']])) {
2159 // type folder links
2160 $folder = $this->getFolder();
2161 $type_formats = Array();
2162 if (!is_null($folder)) {
2163 $type_links = $GLOBALS['SQ_SYSTEM']->am->getLinks($folder->id, SQ_LINK_TYPE_2, 'bodycopy');
2164 foreach ($type_links as $link_info) {
2165 if (isset($parents[$link_info['minorid']])) {
2166 $type_formats[] = $link_info['value'];
2171 // if it's not the page contents bodycopy, it's something that we've
2172 // inherited from the listing engine, so pass it on
2173 parent::onRequestKeywords($broadcaster, $vars);
2175 // if any type formats present, override the asset_position keyword
2176 if (count($type_formats) > 0) {
2177 // set up the 'question_number' alias (mimics asset_position)
2178 $vars['keywords']['asset_position'] = translate('online_quiz_keyword_question_number');
2181 }//end onRequestKeywords()
2197 function _getContentsKeywords()
2199 $keywords = parent::_getContentsKeywords();
2200 $GLOBALS['SQ_SYSTEM']->lm->includeAssetStrings('page_asset_listing');
2203 'error_list' => translate('online_quiz_keyword_error_list'),
2204 'warning_list' => translate('online_quiz_keyword_warning_list'),
2205 'question_range' => translate('online_quiz_keyword_question_range'),
2206 'question_count' => translate('online_quiz_keyword_question_count'),
2209 // unset the next_page_href and previous_page_href for safety (allows for the form
2210 // to change pages without submitting the form to save the questions)
2211 unset($keywords['next_page_href']);
2212 unset($keywords['previous_page_href']);
2216 }//end _getContentsKeywords()
2226 function _getFormKeywords()
2228 $keywords = Array();
2230 $keywords['form_contents'] = translate('cms_form_contents');
2231 $keywords['form_errors'] = translate('cms_form_errors');
2235 }//end _getFormKeywords()
2244 function _getUserDetailsKeywords()
2246 $keywords = Array();
2248 // grab the questions attached to the form
2249 $form = $this->getForm();
2250 if (!is_null($form)) {
2251 $questions = $form->getQuestions(TRUE);
2252 foreach ($questions as $assetid => $question_details) {
2253 list($bridgeid, $shadowid) = explode(':', $assetid);
2254 $keywords['user_details_form_'.$bridgeid.'-'.$shadowid] = 'Form Field: #'.$assetid.' ('.$question_details['name'].')';
2258 // get the generic user to provide us with a list of keywords
2259 $GLOBALS['SQ_SYSTEM']->am->includeAsset('user');
2261 $user_keywords = $user->getAvailableKeywords();
2262 foreach ($user_keywords as $keyword => $description) {
2263 $keywords['user_details_current_user_'.$keyword] = 'Current User: '.$description;
2268 }//end _getUserDetailsKeywords()
2277 function _getResultsKeywords()
2279 $keywords = Array();
2281 $keywords['results_table_full'] = translate('online_quiz_keyword_results_table_full');
2282 $keywords['results_table_simple'] = translate('online_quiz_keyword_results_table_simple');
2286 }//end _getResultsKeywords()
2295 function _getInteractiveKeywords()
2297 $keywords = Array();
2299 $keywords['interactive_question_response_form'] = translate('online_quiz_keyword_interactive_question_response_form');
2300 $keywords['interactive_question_text'] = translate('online_quiz_keyword_interactive_question_text');
2301 $keywords['interactive_question_note'] = translate('online_quiz_keyword_interactive_question_note');
2302 $keywords['interactive_question_number'] = translate('online_quiz_keyword_interactive_question_number');
2303 $keywords['interactive_button'] = translate('online_quiz_keyword_interactive_button');
2304 $keywords['quiz_score'] = translate('online_quiz_keyword_quiz_score');
2308 }//end _getInteractiveKeywords()
2317 function _getQuestionKeywords()
2319 $keywords = Array();
2321 // Refresh the question list, if we are manually configuring the page's question content and adding/removing/editing this order.
2322 // Only do this if the %asset_listing% keyword is missing from the Page Contents bodycopy.
2323 $page_contents_link = $GLOBALS['SQ_SYSTEM']->am->getLink($this->id, SQ_LINK_TYPE_2, 'bodycopy', TRUE, 'page_contents');
2324 if (!empty($page_contents_link)) {
2325 $format_bodycopy = $GLOBALS['SQ_SYSTEM']->am->getAsset($page_contents_link['minorid'], $page_contents_link['minor_type_code']);
2327 require_once SQ_FUDGE_PATH.'/general/text.inc';
2328 $keywords = $format_bodycopy->getKeywords();
2330 if (!in_array('asset_listing', $keywords)) {
2331 $form = $this->getForm();
2332 if (!is_null($form)) {
2333 $questions = $form->getQuestions(TRUE);
2338 // Obtain the available keywords for a quiz question
2339 $GLOBALS['SQ_SYSTEM']->am->includeAsset('online_quiz_question');
2340 $question = new Online_Quiz_Question();
2341 $question_keywords = $question->getAvailableKeywords();
2342 foreach ($question_keywords as $keyword => $description) {
2343 $keywords['question_X_'.$keyword] = 'Question X: '.$description;
2348 }//end _getQuestionKeywords()
2358 function _getQuestionResultKeywords()
2360 $keywords = Array();
2361 $available_keywords = Array(
2362 'question_number' => translate('online_quiz_results_header_question_num'),
2363 'question_text' => translate('online_quiz_results_header_question_text'),
2364 'answer' => translate('online_quiz_results_header_value'),
2365 'answer_text' => translate('online_quiz_results_header_summary'),
2366 'correct_answer' => translate('online_quiz_results_header_correct_value'),
2367 'correct_answer_text' => translate('online_quiz_results_header_correct_summary'),
2368 'points' => translate('online_quiz_results_header_points'),
2369 'available_points' => translate('online_quiz_results_header_available_points'),
2370 'response_supplement' => translate('online_quiz_results_response_supplement'),
2371 'question_note' => translate('online_quiz_results_question_note'),
2374 $locale_text = translate('online_quiz_results_question_x');
2375 foreach ($available_keywords as $keyword => $description) {
2376 $keywords['result_X_'.$keyword] = $locale_text.': '.$description;
2379 // And some more general keywords...
2380 $keywords['quiz_total_points'] = translate('online_quiz_results_quiz_total_points_obtained');
2381 $keywords['quiz_total_available_points'] = translate('online_quiz_results_quiz_maximum_total_points');
2385 }//end _getQuestionResultKeywords()
2395 function _getQuestionGroupResultKeywords()
2397 $keywords = Array();
2398 $keywords['question_group_X_score_category_name'] = translate('online_quiz_results_question_group_x').': '.translate('online_quiz_results_score_category_name');
2399 $keywords['question_group_X_score_category_supplement'] = translate('online_quiz_results_question_group_x').': '.translate('online_quiz_results_score_category_supplement');
2403 }//end _getQuestionGroupResultKeywords()
2406 //-- Keyword Replacements --//
2424 function getKeywordReplacement($keyword)
2426 if (empty($keyword)) return '';
2428 $keyword = parse_keyword($keyword, $modifiers);
2430 if ($this->attr('interactive_mode') && strpos($keyword, 'interactive_') === 0){
2431 if ($keyword == 'interactive_button'){
2432 $replacement = $this->getInteractiveButtonKeywordReplacement();
2434 $replacement = $this->getInteractiveQuestionKeywordReplacement(substr($keyword, strlen('interactive_')));
2436 if (!is_null($replacement)) apply_keyword_modifiers($replacement, $modifiers, Array('assetid' => $this->id));
2437 return $replacement;
2440 if ($keyword == 'quiz_score'){
2441 $replacement = $this->getScoreKeywordReplacement();
2442 apply_keyword_modifiers($replacement, $modifiers, Array('assetid' => $this->id));
2443 return $replacement;
2446 // check the keyword against the dynamic keywords
2447 // in this case - user details:
2449 if (preg_match('/^(user_details_form)_([0-9]*-q[0-9]*)$/', $keyword, $matches)) {
2450 if (isset($matches[1]) && isset($matches[2])) {
2451 // arg = question assetid
2452 $arg = str_replace('-', ':', $matches[2]);
2453 $keyword_stem = $matches[1];
2457 if (preg_match('/^(user_details_current_user)_(.*)$/', $keyword, $matches)) {
2458 if (isset($matches[1]) && isset($matches[2])) {
2459 // if the current user is the public user, the keyword replacements that would've
2460 // been collected below would have been invalid
2461 // return a blank replacement instead
2462 if ($GLOBALS['SQ_SYSTEM']->userPublic()) return '';
2464 // arg = user attribute
2466 $keyword_stem = $matches[1];
2470 if (preg_match('/^(question)_([0-9]*)_(.*)$/', $keyword, $matches)) {
2471 if (isset($matches[1]) && isset($matches[2]) && isset($matches[3])) {
2472 // Keyword match example: question_123_response_form becomes (question, 123, response_form)
2473 $keyword_stem = $matches[1];
2474 $asset_id = $matches[2];
2475 $attr = $matches[3];
2477 // Grab the question keyword
2478 if (!empty($keyword_stem) && !empty($asset_id) && !empty($attr)) {
2479 return $this->getQuestionKeywordReplacement($asset_id, $attr);
2484 // Question and result keywords for the "Thank You
" bodycopy
2485 if (preg_match('/^(result)_([0-9]*)_(.*)$/', $keyword, $matches)) {
2486 if (isset($matches[1]) && isset($matches[2]) && isset($matches[3])) {
2487 // Keyword match example: result_123_answer becomes (result, 123, answer)
2488 $keyword_stem = $matches[1];
2489 $asset_id = $matches[2];
2490 $attr = $matches[3];
2492 // Grab the question result (answers etc.) keyword
2493 if (!empty($keyword_stem) && !empty($asset_id) && !empty($attr)) {
2494 return $this->getQuestionResultKeywordReplacement($asset_id, $attr);
2499 // Question Group result keywords for the "Thank You
" bodycopy
2500 if (preg_match('/^(question_group)_([0-9]*)_(.*)$/', $keyword, $matches)) {
2501 if (isset($matches[1]) && isset($matches[2]) && isset($matches[3])) {
2502 $keyword_stem = $matches[1];
2503 $asset_id = $matches[2];
2504 $attr = $matches[3];
2506 // Grab the question result (answers etc.) keyword
2507 if (!empty($keyword_stem) && !empty($asset_id) && !empty($attr)) {
2508 return $this->getQuestionGroupResultKeywordReplacement($asset_id, $attr);
2513 // setup the replacement function call
2514 if (!empty($keyword_stem) && !empty($arg)) {
2515 $func_name = 'get'.ucwords_no_space($keyword_stem).'KeywordReplacement';
2516 if (method_exists($this, $func_name)) {
2517 return $this->$func_name($arg);
2521 // otherwise, fall back to the parent
2522 $replacement = parent::getKeywordReplacement($keyword);
2523 if (!is_null($replacement)) apply_keyword_modifiers($replacement, $modifiers, Array('assetid' => $this->id));
2525 return $replacement;
2527 }//end getKeywordReplacement()
2538 function getInteractiveQuestionKeywordReplacement($keyword)
2540 $replacement = NULL;
2542 $question_pagination = $this->loadQuestionPagination();
2543 $current_result_page = $this->getCurrentPage();
2545 $question_id = key($question_pagination['pages_to_questions'][$current_result_page]);
2546 $question = $GLOBALS['SQ_SYSTEM']->am->getAsset($question_id, 'online_quiz_question_multichoice');
2547 if ((is_null($question))) return $replacement;
2550 case 'question_response_form':
2551 $current_status = $question_pagination['pages_to_status'][$current_result_page];
2552 if (strpos($current_status, 'feedback') !== FALSE){
2553 //print the question but with disabled fields and add special classes & tags.
2554 $replacement = $question->getResponseFormKeywordReplacement($this->attr('question_option_format'), TRUE);
2556 $replacement = $question->getResponseFormKeywordReplacement($this->attr('question_option_format'));
2559 case 'question_note':
2560 $replacement = $question->getQuestionNoteKeywordReplacement();
2562 case 'question_text':
2563 $replacement = $question->getQuestionTextKeywordReplacement();
2565 case 'question_number':
2566 $replacement = $question->getQuestionNumberKeywordReplacement();
2570 return $replacement;
2572 }//end getInteractiveQuestionKeywordReplacement()
2582 function getInteractiveButtonKeywordReplacement()
2584 $prefix = $this->getPrefix();
2585 $current_result_page = $this->getCurrentPage();
2586 $question_pagination = $this->loadQuestionPagination();
2590 $current_status = $question_pagination['pages_to_status'][$current_result_page];
2591 if ($current_status == 'feedback_retry'){
2592 submit_button($prefix.'_submit_retry_button', $this->attr('retry_button_text'));
2593 } else if ($current_status == 'feedback_last'){
2594 submit_button($prefix.'_submit_button', $this->attr('submit_button_text'));
2595 } else if ($current_status == 'feedback_next'){
2596 submit_button($prefix.'_submit_next_button', $this->attr('next_button_text'));
2597 } else if (strpos($current_status, 'submit_question') === 0){
2598 //using this so we can have JS validation for the currently displayed question.
2599 echo $this->getSubmitButtonKeywordReplacement($prefix.'_submit_question_button', $this->attr('submit_question_button_text'));
2602 return ob_get_clean();
2605 }//end getInteractiveButtonKeywordReplacement()
2615 function getScoreKeywordReplacement()
2617 $replacement = $this->attr('score_format');
2619 if ($this->attr('interactive_mode')) {
2621 //Number of questions done so far
2622 $total_questions = 0;
2623 if (!empty($_SESSION[SQ_ONLINE_QUIZ_SESSION_VAR]['quiz'][$this->id]['interactive_score']['total_questions'])){
2624 $total_questions = $_SESSION[SQ_ONLINE_QUIZ_SESSION_VAR]['quiz'][$this->id]['interactive_score']['total_questions'];
2627 //Don't display the score if we havn't answered any questions yet. i.e first page.
2628 if ($total_questions < 1) return NULL;
2630 //Number of questions answered correctly.
2631 $correct_answers = 0;
2632 if (!empty($_SESSION[SQ_ONLINE_QUIZ_SESSION_VAR]['quiz'][$this->id]['interactive_score']['correct_answers'])){
2633 $correct_answers = $_SESSION[SQ_ONLINE_QUIZ_SESSION_VAR]['quiz'][$this->id]['interactive_score']['correct_answers'];
2636 //Number of question retries so far
2638 if (!empty($_SESSION[SQ_ONLINE_QUIZ_SESSION_VAR]['quiz'][$this->id]['interactive_score']['retries'])){
2639 $retries = $_SESSION[SQ_ONLINE_QUIZ_SESSION_VAR]['quiz'][$this->id]['interactive_score']['retries'];
2642 $total_questions_plus_retries = $total_questions + $retries;
2644 $replacement = str_replace('%correct_answers%', $correct_answers, $replacement);
2645 $replacement = str_replace('%total_questions%', $total_questions, $replacement);
2646 $replacement = str_replace('%total_questions_plus_retries%', $total_questions_plus_retries, $replacement);
2647 $replacement = str_replace('%total_retries%', $retries, $replacement);
2650 //these only work in the thank you bodycopy.
2651 $question_results = $this->getResults();
2652 if (isset($question_results['totals']['points'])){
2653 $replacement = str_replace('%quiz_total_points%', $question_results['totals']['points'], $replacement);
2655 if (isset($question_results['totals']['available_points'])){
2656 $replacement = str_replace('%quiz_total_available_points%', $question_results['totals']['available_points'], $replacement);
2659 return $replacement;
2661 }//end getScoreKeywordReplacement()
2672 function getUserDetailsFormKeywordReplacement($questionid)
2674 $user_details = $this->getUserDetails();
2676 if (!empty($user_details)) {
2677 $return = array_get_index($user_details, $questionid, '');
2682 }//end getUserDetailsFormKeywordReplacement()
2693 function getUserDetailsCurrentUserKeywordReplacement($keyword)
2695 // ask the user asset to get the replacement for us
2696 return $GLOBALS['SQ_SYSTEM']->user->getKeywordReplacement('asset_'.$keyword);
2698 }//end getUserDetailsCurrentUserKeywordReplacement()
2712 function getSubmitButtonKeywordReplacement($field_name = '', $button_text = '')
2714 if (empty($field_name)){
2715 $prefix = $this->getPrefix();
2716 $field_name = $prefix.'_submit_button';
2719 $this->registerFormField($field_name);
2721 if (empty($button_text)) {
2722 $button_text = $this->attr('submit_button_text');
2725 // construct the javascript here
2728 if ($this->attr('clientside_validation')) {
2730 <script type="text/javascript
">
2738 function print_error_summary()
2740 form = document.getElementById("<?php echo $this->
getPrefix(); ?>
");
2747 var error_stack = new Array();
2749 error_stack["errors
"] = new Array();
2750 error_stack["warnings
"] = new Array();
2753 $errors = array_get_index($this->_error_stack, 'errors', Array());
2754 foreach ($errors as $idx => $error) {
2756 error_stack["errors
"][<?php echo $idx; ?>] = "<?php echo str_replace(
'"',
'\"', $error); ?>
";
2760 $warnings = array_get_index($this->_error_stack, 'warnings', Array());
2761 foreach ($warnings as $idx => $warning) {
2763 error_stack["warnings
"][<?php echo $idx; ?>] = "<?php echo str_replace(
'"',
'\"', $warning); ?>
";
2767 // getQuestionPagination allows us to skip
2768 // reloading and chunking the question assets
2769 $pages = array_get_index($this->loadQuestionPagination(), 'pages_to_questions', Array());
2770 $current_questions = array_get_index($pages, $this->getCurrentPage(), Array());
2771 foreach ($current_questions as $assetid => $type) {
2772 $question = $GLOBALS['SQ_SYSTEM']->am->getAsset($assetid);
2773 if (!is_null($question)) {
2774 echo $question->getValidationJS();
2775 $GLOBALS['SQ_SYSTEM']->am->forgetAsset($question);
2780 if (error_stack["errors
"].length) {
2781 summary += "The following errors are present:\n
";
2782 for (var idx in error_stack["errors
"]) {
2783 summary += " -
" + error_stack["errors
"][idx] + "\n
";
2789 if (error_stack["warnings
"].length > 0) {
2790 summary += "The following warnings are present:\n
";
2791 for (var idx in error_stack["warnings
"]) {
2792 summary += " -
" + error_stack["warnings
"][idx] + "\n
";
2795 if (!box_type.length) {
2796 summary += "\nAre you sure you want to
continue?
";
2797 box_type = "confirm
";
2801 if (box_type == "alert
") {
2804 } else if (box_type == "confirm
") {
2805 return confirm(summary);
2810 }//end function print_error_summary()
2815 $button_js = 'return print_error_summary();';
2816 }//end if (clientside_validation)
2818 submit_button($field_name, $button_text, $button_js);
2819 return ob_get_clean();
2821 }//end getSubmitButtonKeywordReplacement()
2830 function getErrorListKeywordReplacement()
2832 $errors = array_get_index($this->_error_stack, 'errors', Array());
2833 if (!empty($errors)) {
2836 foreach ($errors as $error) {
2837 ?><li><?php echo $error; ?></li><?php
2840 return ob_get_clean();
2845 }//end getErrorListKeywordReplacement()
2854 function getWarningListKeywordReplacement()
2856 $warnings = array_get_index($this->_error_stack, 'warnings', Array());
2857 if (!empty($warnings)) {
2860 foreach ($warnings as $warning) {
2861 ?><li><?php echo $warning; ?></li><?php
2864 return ob_get_clean();
2869 }//end getWarningListKeywordReplacement()
2878 function getQuestionRangeKeywordReplacement()
2880 $question_pagination = $this->loadQuestionPagination();
2881 $pages_to_questions = array_get_index($question_pagination, 'pages_to_questions', Array());
2882 $questions_to_pages = array_get_index($question_pagination, 'questions_to_pages', Array());
2883 $current_page_assets = array_get_index($pages_to_questions, $this->getCurrentPage(), Array());
2887 foreach ($current_page_assets as $assetid => $type) {
2888 if (is_null($first)) {
2889 $first_asset = array_get_index($questions_to_pages, $assetid, Array());
2890 $first = array_get_index($first_asset, 'list_position', NULL);
2893 // keep grabbing items, in case it's the last one
2894 $last_asset = array_get_index($questions_to_pages, $assetid, Array());
2895 $last = array_get_index($last_asset, 'list_position', NULL);
2898 if (is_null($first) || is_null($last)) {
2902 return $first.' - '.$last;
2904 }//end getQuestionRangeKeywordReplacement()
2913 function getQuestionCountKeywordReplacement()
2915 if ($this->attr('interactive_mode')){
2916 $question_pagination = $this->loadQuestionPagination();
2917 //one question per page so number of questions = number of pages.
2918 return count($question_pagination['pages_to_questions']);
2920 return count($this->getQuestions());
2923 }//end getQuestionCountKeywordReplacement()
2936 function getResultsTableKeywordReplacement($show_columns=NULL, $show_totals=TRUE, $html=TRUE)
2938 if (!is_array($show_columns)) {
2940 $show_columns = Array(
2941 'question_num' => translate('online_quiz_results_header_question_num'),
2942 'points' => translate('online_quiz_results_header_points'),
2943 'available_points' => translate('online_quiz_results_header_available_points'),
2947 // slight hack - tabs show up when printing plain text, but not when displaying as html
2948 $available_columns = Array(
2949 'question_num' => translate('online_quiz_results_header_question_num'),
2950 'assetid' => translate('online_quiz_results_header_assetid'),
2951 'question_text' => translate('online_quiz_results_header_question_text'),
2952 'value' => translate('online_quiz_results_header_value'),
2953 'summary' => translate('online_quiz_results_header_summary'),
2954 'correct_value' => translate('online_quiz_results_header_correct_value'),
2955 'correct_summary' => translate('online_quiz_results_header_correct_summary'),
2956 'points' => translate('online_quiz_results_header_points'),
2957 'available_points' => translate('online_quiz_results_header_available_points'),
2960 // plain-text column formatting:
2961 $column_name_suffix = ': ';
2962 $longest_column_length = 0;
2965 foreach ($show_columns as $column => $column_title) {
2966 if (isset($available_columns[$column])) {
2967 $columns[$column] = $column_title;
2968 if (strlen($column_title) > $longest_column_length) {
2969 $longest_column_length = strlen($column_title);
2974 $results = $this->getResults();
2976 if (!empty($results) && !empty($columns)) {
2979 // HACK: hardcode a short name for the CSS class, to get around problems with long class names and Mac IE
2980 $css_class_prefix = str_replace('_', '-', 'quiz_res');
2984 <table class="<?php echo $css_class_prefix; ?>
" id="<?php echo $css_class_prefix.
'-'.$this->id; ?>
">
2988 $column_counter = 1;
2989 foreach ($columns as $column => $column_name) {
2990 ?><th class="<?php echo $css_class_prefix.
'-c'.$column_counter; ?>
"><?php echo $column_name; ?></th><?php
3000 foreach (array_get_index($results, 'questions', Array()) as $question_num => $question_results) {
3007 $column_counter = 1;
3008 foreach ($columns as $column => $column_name) {
3009 $alignment_padding = '';
3011 ?><td class="<?php echo $css_class_prefix.
'-c'.$column_counter; ?> <?php echo $css_class_prefix.
'-r'.$row_counter; ?>
"><?php
3015 echo $column_name_suffix;
3016 for ($ii = 0; $ii < ($longest_column_length - strlen($column_name)); $ii++) {
3017 $alignment_padding .= ' ';
3020 for ($ii = 0; $ii < strlen($column_name.$column_name_suffix); $ii++) {
3021 $alignment_padding .= ' ';
3028 case 'question_num':
3032 case 'question_text':
3033 $question = $GLOBALS['SQ_SYSTEM']->am->getAsset($question_results['assetid']);
3034 if (!is_null($question)) {
3036 echo $question->getQuestionText();
3037 $question_text = ob_get_clean();
3039 // a hack to make bodycopy-derived question text appear normal when sending a plain-text email
3040 $question_text = trim(strip_tags($question_text));
3041 $question_text = html_entity_decode($question_text);
3044 $question_text = str_replace("\n
", "\n
".$alignment_padding, $question_text);
3046 echo $question_text;
3047 $GLOBALS['SQ_SYSTEM']->am->forgetAsset($question);
3053 case 'correct_value':
3055 case 'available_points':
3056 echo array_get_index($question_results, $column);
3061 case 'correct_summary':
3063 // explode into <li>
3064 $summary_text = array_get_index($question_results, $column, '');
3065 if (!empty($summary_text)) {
3066 $summary_array = explode("\n
", array_get_index($question_results, $column, ''));
3067 if (!empty($summary_array)) {
3069 foreach ($summary_array as $summary_item) {
3078 // indent each new line
3079 echo str_replace("\n
", "\n
".$alignment_padding, array_get_index($question_results, $column));
3084 $cell_contents = ob_get_clean();
3085 if ($html && !strlen($cell_contents)) {
3086 echo translate('online_quiz_results_empty_cell');
3088 echo $cell_contents;
3097 }//end foreach ($columns)
3108 }//end foreach ($results['questions'])
3110 // check if either points or available_points is set, if so
3111 // replace question_num, assetid or the column to the left
3112 // of the first points column with "Total
"
3115 $points_columns_counter = 0;
3116 $points_column = FALSE;
3117 $available_points_column = FALSE;
3118 if (isset($columns['points'])) {
3119 $points_columns_counter++;
3120 $points_column = TRUE;
3122 if (isset($columns['available_points'])) {
3123 $points_columns_counter++;
3124 $available_points_column = TRUE;
3127 // if we have at least one point column
3128 if ($points_columns_counter) {
3132 $column_counter = 0;
3133 foreach ($columns as $column => $column_name) {
3134 ?><td class="<?php echo $css_class_prefix.
'_c'.($column_counter + 1); ?>
"><?php
3136 // is this the first column, and are there enough columns to support a "Total
" label?
3137 // also make sure the first column isn't a points column
3138 if ($column == 'points' || $column == 'available_points') {
3139 echo $results['totals'][$column];
3141 if ($column_counter == 0 && count($columns) > $points_columns_counter + 1) {
3143 echo translate('online_quiz_results_header_totals');
3145 // otherwise print an "empty
" cell
3146 echo translate('online_quiz_results_empty_cell');
3153 }//end for (columns)
3157 // plain-text column formatting:
3158 $longest_column_length = 0;
3159 $totals_columns = Array(
3160 translate('online_quiz_results_header_total_points'),
3161 translate('online_quiz_results_header_total_available_points'),
3163 foreach ($totals_columns as $column_name) {
3164 if (strlen($column_name) > $longest_column_length) {
3165 $longest_column_length = strlen($column_name);
3169 foreach ($columns as $column => $column_name) {
3170 if ($column == 'points' || $column == 'available_points') {
3171 echo translate('online_quiz_results_header_total_'.$column);
3172 echo $column_name_suffix;
3173 for ($ii = 0; $ii < ($longest_column_length - strlen($column_name)); $ii++) {
3176 echo $results['totals'][$column];
3182 }//end if ($points_columns_counter)
3183 }//end if ($show_totals)
3190 $return = ob_get_clean();
3191 }//end if (!empty($results) && !empty($columns))
3195 }//end getResultsTableKeywordReplacement()
3206 function getResultsTableFullKeywordReplacement($html=TRUE)
3209 'question_num' => translate('online_quiz_results_header_question_num'),
3210 'question_text' => translate('online_quiz_results_header_question_text'),
3211 'value' => translate('online_quiz_results_header_value'),
3212 'summary' => translate('online_quiz_results_header_summary'),
3213 'correct_value' => translate('online_quiz_results_header_correct_value'),
3214 'correct_summary' => translate('online_quiz_results_header_correct_summary'),
3215 'points' => translate('online_quiz_results_header_points'),
3216 'available_points' => translate('online_quiz_results_header_available_points'),
3217 'response_supplement' => translate('online_quiz_results_header_available_points'),
3219 return $this->getResultsTableKeywordReplacement($columns, TRUE, $html);
3221 }//end getResultsTableFullKeywordReplacement()
3230 function getResultsTableFullTextKeywordReplacement()
3232 return $this->getResultsTableFullKeywordReplacement(FALSE);
3234 }//end getResultsTableFullTextKeywordReplacement()
3245 function getResultsTableSimpleKeywordReplacement($html=TRUE)
3248 'question_num' => translate('online_quiz_results_header_question_num'),
3249 'value' => translate('online_quiz_results_header_value'),
3250 'correct_value' => translate('online_quiz_results_header_correct_value'),
3251 'points' => translate('online_quiz_results_header_points'),
3252 'available_points' => translate('online_quiz_results_header_available_points'),
3254 return $this->getResultsTableKeywordReplacement($columns, TRUE, $html);
3256 }//end getResultsTableSimpleKeywordReplacement()
3265 function getResultsTableSimpleTextKeywordReplacement()
3267 return $this->getResultsTableSimpleKeywordReplacement(FALSE);
3269 }//end getResultsTableSimpleTextKeywordReplacement()
3281 function getQuestionKeywordReplacement($question_asset_id, $keyword)
3283 $replacement = '%question_'.$question_asset_id.'_'.$keyword.'%';
3285 $question = $GLOBALS['SQ_SYSTEM']->am->getAsset($question_asset_id, 'online_quiz_question_multichoice');
3286 if ((!is_null($question)) && ($question->readAccess())) {
3287 $replacement = $question->getKeywordReplacement($keyword);
3288 $GLOBALS['SQ_SYSTEM']->am->forgetAsset($question);
3291 return $replacement;
3293 }//end getQuestionKeywordReplacement()
3305 function getQuestionResultKeywordReplacement($question_asset_id, $keyword)
3307 $replacement = '%result_'.$question_asset_id.'_'.$keyword.'%';
3309 $question = $GLOBALS['SQ_SYSTEM']->am->getAsset($question_asset_id, 'online_quiz_question_multichoice');
3310 if ((!is_null($question)) && ($question->readAccess())) {
3311 $question_results = $question->getResults();
3313 // Some replacements are not provided in the question results, so we have to ask for these...
3314 $keyword_replaced = FALSE;
3317 case 'question_number': $replacement = $question->getPosition();
3318 $keyword_replaced = TRUE;
3321 case 'question_text': $replacement = $question->getKeywordReplacement('question_text');
3322 $keyword_replaced = TRUE;
3325 case 'question_text_plain': $replacement = trim(strip_tags($question->getKeywordReplacement('question_text')));
3326 $keyword_replaced = TRUE;
3329 case 'question_note': $replacement = $question->getQuestionNote();
3330 $keyword_replaced = TRUE;
3333 case 'question_note_plain': $replacement = trim(strip_tags($question->getQuestionNote()));
3334 $keyword_replaced = TRUE;
3337 case 'answer': $keyword = 'value';
3340 case 'answer_text': $keyword = 'summary';
3343 case 'answer_text_plain': if (isset($question_results['summary'])) {
3344 $replacement = trim(strip_tags($question_results['summary']));
3345 $keyword_replaced = TRUE;
3349 case 'correct_answer': $keyword = 'correct_value';
3352 case 'correct_answer_text': $keyword = 'correct_summary';
3355 case 'correct_answer_text_plain': if (isset($question_results['correct_summary'])) {
3356 $replacement = trim(strip_tags($question_results['correct_summary']));
3357 $keyword_replaced = TRUE;
3361 case 'response_supplement': $replacement = $question->getResponseSupplement();
3364 case 'response_supplement_text': $replacement = trim(strip_tags($question->getResponseSupplement()));
3368 // This keyword is obtained from the results...
3369 if (!$keyword_replaced) {
3370 if (isset($question_results[$keyword])) {
3371 $replacement = $question_results[$keyword];
3375 $GLOBALS['SQ_SYSTEM']->am->forgetAsset($question);
3378 return $replacement;
3380 }//end getQuestionResultKeywordReplacement()
3391 function getQuizTotalPointsKeywordReplacement()
3395 $quiz_result = $this->getResults();
3396 $total_points = $quiz_result['totals']['points'];
3398 return $total_points;
3400 }//end getQuizTotalPointsKeywordReplacement()
3411 function getQuizTotalAvailablePointsKeywordReplacement()
3415 $quiz_result = $this->getResults();
3416 $total_points = $quiz_result['totals']['available_points'];
3418 return $total_points;
3420 }//end getQuizTotalAvailablePointsKeywordReplacement()
3432 function getQuestionGroupResultKeywordReplacement($question_group_asset_id, $keyword)
3434 $replacement = '%question_group_'.$question_group_asset_id.'_'.$keyword.'%';
3436 $question_group = $GLOBALS['SQ_SYSTEM']->am->getAsset($question_group_asset_id, 'online_quiz_question_group');
3437 if ((!is_null($question_group)) && ($question_group->readAccess())) {
3438 $group_questions = array_keys($question_group->getQuestions());
3439 $quiz_questions = array_keys($this->getQuestions());
3441 // Add up the totals for the questions which have been asked
3442 $questions_asked = array_intersect($quiz_questions, $group_questions);
3445 $group_questions = NULL;
3446 $quiz_questions = NULL;
3449 foreach ($questions_asked as $question_asset_id) {
3450 $question = $GLOBALS['SQ_SYSTEM']->am->getAsset($question_asset_id);
3451 if (!is_null($question)) {
3452 $section_total += $question->getPoints();
3456 $score_category = $question_group->getScoreCategoryForScore($section_total);
3457 if (!is_null($score_category)) {
3459 case 'score_category_name': $replacement = $score_category['name'];
3462 case 'score_category_supplement': $replacement = $score_category['content'];
3464 // replace internal links to pages and images with their full URLs
3466 preg_match_all('|\./\?a=([0-9]+)|', $replacement, $matches);
3467 $urls = $GLOBALS['SQ_SYSTEM']->am->getAssetURL(array_unique($matches[1]));
3468 foreach ($urls as $assetid => $url) {
3469 $replacement = preg_replace('|\./\?a='.$assetid.'([^0-9])|', $url.'\\1', $replacement);
3473 case 'score_category_supplement_text': $replacement = strip_tags($score_category['content']);
3479 return $replacement;
3481 }//end getQuestionGroupResultKeywordReplacement()
3490 function _getFormSubmitMethod()
3494 }//end _getFormSubmitMethod()
3497 //-- Listing Functions --//
3508 function getCurrentPage()
3510 if ($this->attr('interactive_mode')){
3513 if (isset($_SESSION[SQ_ONLINE_QUIZ_SESSION_VAR]['quiz'][$this->id]['interactive_page'])) {
3514 $result_page = (int)$_SESSION[SQ_ONLINE_QUIZ_SESSION_VAR]['quiz'][$this->id]['interactive_page'];
3517 if ($result_page <= 0) $result_page = 1;
3519 return $result_page;
3522 $asset_result_page_var = 'quiz_'.$this->id.'_result_page';
3523 $generic_result_page_var = 'result_page';
3525 // have [assetid]_result_page take precedence over result_page
3527 if (isset($_REQUEST[$generic_result_page_var])) {
3528 $result_page = (int)$_REQUEST[$generic_result_page_var];
3530 if (isset($_REQUEST[$asset_result_page_var])) {
3531 $result_page = (int)$_REQUEST[$asset_result_page_var];
3534 if ($result_page <= 0) $result_page = 1;
3536 return $result_page;
3539 }//end getCurrentPage()
3555 function &getPageAssets(&$children, &$replacements, $result_page=NULL)
3557 // the list is sorted and positions set, now we can split to groups
3558 if ($this->attr('group_by') == 'grouped') {
3559 $this->groupAssetsRecursively($this->attr('asset_grouping'), $children, $children);
3560 $this->sortGroups($this->attr('asset_grouping'), $children, $children);
3563 $num_per_page = $this->_getNumPerPage();
3565 if (is_null($result_page) || $result_page <= 0) {
3566 $result_page = $this->getCurrentPage();
3568 $result_page = (int)$result_page;
3570 // get our page chunk here
3571 $todo =& $this->getChunk($children, $replacements, Array(), $result_page, $num_per_page);
3573 //Bug #5283: Need to extract the page ids from the grouping structure
3574 if ($this->attr('group_by') == 'grouped') {
3575 for ($i = 0; $i < count($this->attr('asset_grouping')); $i++){ //group levels
3576 $todo_pages = Array();
3577 foreach($todo as $group_key => $group_data){
3578 foreach($group_data as $key => $value){
3579 $todo_pages[$key] = $value;
3582 $todo = $todo_pages; //$todo will be the final traversal
3588 }//end getPageAssets()