Squiz Matrix  4.12.2
 All Data Structures Namespaces Functions Variables Pages
page_online_quiz_edit_fns.inc
1 <?php
18 require_once SQ_PACKAGES_PATH.'/cms/page_templates/page_asset_listing/page_asset_listing_edit_fns.inc';
19 require_once SQ_FUDGE_PATH.'/datetime_field/datetime_field.inc';
20 require_once SQ_FUDGE_PATH.'/general/datetime.inc';
21 
22 
37 {
38 
39 
46  function __construct()
47  {
48  parent::__construct();
49 
50  }//end constructor
51 
52 
64  function paintUserDetailsSource(&$asset, &$o, $prefix)
65  {
66  $write_access = $asset->writeAccess('attributes');
67 
68  $attr = $asset->getAttribute('user_details_source');
69  $attr->paint($prefix.'_'.$attr->id, !$write_access);
70 
71  $form = $asset->getForm();
72  if (!is_null($form)) {
73  echo '<p>'.get_asset_tag_line($form->id, 'details').'</p>';
74  }
75  $GLOBALS['SQ_SYSTEM']->am->forgetAsset($form);
76 
77  $bodycopy = $asset->getBodycopy('user_details');
78  if (!is_null($bodycopy)) {
79  echo '<p>'.get_asset_tag_line($bodycopy->id, 'contents').'</p>';
80  }
81  $GLOBALS['SQ_SYSTEM']->am->forgetAsset($bodycopy);
82 
83  return $write_access;
84 
85  }//end paintUserDetailsSource()
86 
87 
99  function processUserDetailsSource(&$asset, &$o, $prefix)
100  {
101  $write_access = $asset->writeAccess('attributes');
102 
103  if ($write_access) {
104  $attr = $asset->getAttribute('user_details_source');
105  $attr->process($prefix.'_'.$attr->id);
106  if (!$attr->processed || !$asset->setAttrValue($attr->name, $attr->value)) {
107  // bail now if we can't process the attribute properly
108  return FALSE;
109  }
110  }
111 
112  return $write_access;
113 
114  }//end processUserDetailsSource()
115 
116 
128  function paintAfterSubmitAction(&$asset, &$o, $prefix)
129  {
130  $write_access = $asset->writeAccess('attributes') && $asset->writeAccess('links');
131 
132  $attr = $asset->getAttribute('after_submit_action');
133  $attr->paint($prefix.'_'.$attr->id, !$write_access);
134 
135  if ($attr->value == 'thank_you') {
136  $bodycopy = $asset->getBodycopy('thank_you');
137  if (!is_null($bodycopy)) {
138  echo '<p>'.get_asset_tag_line($bodycopy->id, 'contents').'</p>';
139  }
140  $GLOBALS['SQ_SYSTEM']->am->forgetAsset($bodycopy);
141  }
142 
143  return $write_access;
144 
145  }//end paintAfterSubmitAction()
146 
147 
159  function processAfterSubmitAction(&$asset, &$o, $prefix)
160  {
161  $write_access = $asset->writeAccess('attributes') && $asset->writeAccess('links');
162 
163  if ($write_access) {
164  $attr = $asset->getAttribute('after_submit_action');
165  $attr->process($prefix.'_'.$attr->id);
166  if (!$attr->processed || !$asset->setAttrValue($attr->name, $attr->value)) {
167  // bail now if we can't process the attribute properly
168  return FALSE;
169  }
170 
171  // if form is selected, set up the thank_you bodycopy
172  $enable_bodycopy = ($attr->value == 'thank_you');
173  $asset->setBodycopy('thank_you', $enable_bodycopy);
174  }
175 
176  return $write_access;
177 
178  }//end processAfterSubmitAction()
179 
180 
192  function processCanRetake(&$asset, &$o, $prefix)
193  {
194  $write_access = $asset->writeAccess('attributes') && $asset->writeAccess('links');
195 
196  if ($write_access) {
197  $attr = $asset->getAttribute('can_retake');
198  $attr->process($prefix.'_'.$attr->id);
199  if (!$attr->processed || !$asset->setAttrValue($attr->name, $attr->value)) {
200  // bail now if we can't process the attribute properly
201  return FALSE;
202  }
203 
204  // if form is selected, set up the thank_you bodycopy
205  // can_retake == TRUE means we don't need the "Already Taken" bodycopy
206  $enable_bodycopy = !($attr->value);
207  $asset->setBodycopy('already_taken', $enable_bodycopy);
208  }
209 
210  return $write_access;
211 
212  }//end processCanRetake()
213 
214 
226  function paintCanRetake(&$asset, &$o, $prefix)
227  {
228  $write_access = $asset->writeAccess('attributes') && $asset->writeAccess('links');
229 
230  $attr = $asset->getAttribute('can_retake');
231  $attr->setEditParam('true_text', translate('yes'));
232  $attr->setEditParam('false_text', translate('no'));
233  $attr->paint($prefix.'_'.$attr->id, !$write_access);
234 
235  if ($attr->value == FALSE) {
236  $bodycopy = $asset->getBodycopy('already_taken');
237  if (!is_null($bodycopy)) {
238  echo '<p>'.get_asset_tag_line($bodycopy->id, 'contents').'</p>';
239  }
240  $GLOBALS['SQ_SYSTEM']->am->forgetAsset($bodycopy);
241  }
242 
243  return $write_access;
244 
245  }//end paintCanRetake()
246 
247 
258  function paintDefaultFormatLinks(&$asset, &$o, $prefix)
259  {
260  ?>
261  <table class="sq-backend-table">
262  <tr>
263  <th><?php echo translate('edit_format') ?></th>
264  <th><?php echo translate('note') ?></th>
265  </tr>
266  <?php
267  $bodycopies = $asset->_bodycopies;
268 
269  // manually print page_contents and no_results
270  unset($bodycopies['page_contents']);
271  unset($bodycopies['no_results']);
272  $this->_paintDefaultFormatLink($asset->id, 'page_contents', translate('cms_listing_page_contents_desc'));
273  $this->_paintDefaultFormatLink($asset->id, 'no_results', translate('cms_listing_no_results_bodycopy_desc'));
274 
275  foreach ($bodycopies as $bodycopy_code => $bodycopy_name) {
276  $this->_paintDefaultFormatLink($asset->id, $bodycopy_code, translate('online_quiz_bodycopy_'.$bodycopy_code.'_desc'));
277  }
278  $this->_paintDefaultFormatLink($asset->id, 'user_details', translate('online_quiz_form_user_details_desc'), 'simple_form', 'details');
279 
280  $folder = $asset->getFolder('type_formats');
281  $this->_paintDefaultFormatLink($folder->id, 'default_format', translate('cms_listing_default_asset_desc'));
282  ?>
283  </table>
284  <?php
285 
286  return FALSE;
287 
288  }//end paintDefaultFormatLinks()
289 
290 
301  function paintDownloadDateRange(&$asset, &$o, $prefix)
302  {
303  $parameters = Array(
304  'min' => '2003-01-01 00:00:00',
305  'max' => ts_iso8601(time()),
306  'allow_circa' => '0',
307  'show' => Array('y', 'm', 'd'),
308  'null' => Array(),
309  'style' => Array(
310  'y' => 's',
311  'm' => 's',
312  'd' => 's',
313  ),
314  );
315 
316  $parameters['print_format'] = 'j M Y';
317 
318  $from_value = isset($_POST[$prefix.'_export_fromvalue']) ? ts_iso8601(mktime(0,0,0,$_POST[$prefix.'_export_fromvalue']['m'],$_POST[$prefix.'_export_fromvalue']['d'],$_POST[$prefix.'_export_fromvalue']['y'])) : date('Y-m-d', time()-7*86400).' --:--:--';
319  $to_value = isset($_POST[$prefix.'_export_tovalue']) ? ts_iso8601(mktime(0,0,0,$_POST[$prefix.'_export_tovalue']['m'],$_POST[$prefix.'_export_tovalue']['d'],$_POST[$prefix.'_export_tovalue']['y'])) : date('Y-m-d').' --:--:--';
320 
321  $from = new Datetime_Field($prefix.'_export_from', $from_value, $parameters);
322  $to = new Datetime_Field($prefix.'_export_to', $to_value, $parameters);
323 
324  $from->printField();
325  echo ' '.translate('to').' ';
326  $to->printField();
327 
328  }//end paintDownloadDateRange()
329 
330 
341  function paintDownloadFormat(&$asset, &$o, $prefix)
342  {
343  $options = Array(
344  '' => '------- '.translate('please_select').' -------',
345  'csv' => translate('online_quiz_download_csv'),
346  'csv_nhr' => translate('online_quiz_download_csv_nhr'),
347  );
348 
349  echo combo_box($prefix.'_export_format', $options, FALSE, '');
350  echo hidden_field($prefix.'_export_switch', '0');
351 
352  $delimiter_text = isset($_POST[$prefix.'_delimiter']) ? $_POST[$prefix.'_delimiter'] : ',';
353  echo ' &nbsp; Delimiter &nbsp;';
354  echo text_box($prefix.'_delimiter',$delimiter_text,1,1,TRUE);
355 
356  }//end paintDownloadFormat()
357 
358 
369  function paintDownloadFields(&$asset, &$o, $prefix)
370  {
371  // Grab all available questions
372  $user_details_form = $asset->getForm();
373  $user_details_form_questions = $user_details_form->getQuestions();
374  $quiz_questions = $asset->getQuestions(TRUE, TRUE);
375 
376  echo check_box($prefix.'_export_fields_select_all', '1', '', 'sq_set_check_all(this.form, "'.$prefix.'_export_fields[]", this.checked);').'<b>'.translate('select_all').'</b>';
377  echo '<br><br>';
378 
379  echo '<p><b>Submission Details</b><br>';
380  echo check_box($prefix.'_export_fields[]', '__time__', '1').translate('submission_time').'<br/>';
381  echo check_box($prefix.'_export_fields[]', '__user__', '1').translate('online_quiz_user_id').'<br/>';
382  echo check_box($prefix.'_export_fields[]', '__ipaddress__', '1').translate('online_quiz_ip_address').'<br/>';
383  echo check_box($prefix.'_export_fields[]', '__score__', '1').translate('online_quiz_score').'<br/>';
384  echo '</p>';
385 
386 
387  if (!empty($user_details_form_questions)) {
388  echo '<p><b>User Details Form Questions</b><br>';
389  foreach ($user_details_form_questions as $user_details_form_question_assetid => $user_details_form_question_details) {
390  $user_details_form_question = $GLOBALS['SQ_SYSTEM']->am->getAsset($user_details_form_question_assetid);
391  $user_details_form_questions[$user_details_form_question_assetid] = $user_details_form_question->getVal('title');
392 
393  echo check_box($prefix.'_export_fields[]', $user_details_form_question_assetid, '1');
394  echo $user_details_form_questions[$user_details_form_question_assetid].'<br/>';
395 
396  $GLOBALS['SQ_SYSTEM']->am->forgetAsset($user_details_form_question);
397  }
398  echo '</p>';
399  }
400 
401  if (!empty($quiz_questions)) {
402  echo '<p><b>Quiz Questions</b><br>';
403  $q_num = 1;
404  foreach ($quiz_questions as $quiz_question_assetid => $quiz_question_details) {
405  $quiz_question = $GLOBALS['SQ_SYSTEM']->am->getAsset($quiz_question_assetid);
406  $quiz_questions[$quiz_question_assetid] = trim(strip_tags($quiz_question->getQuestionText()));
407 
408  echo check_box($prefix.'_export_fields[]', $quiz_question_assetid, '1');
409  echo 'Q'.$q_num.'. '.$quiz_questions[$quiz_question_assetid].'<br/>';
410  $q_num++;
411 
412  $GLOBALS['SQ_SYSTEM']->am->forgetAsset($quiz_question);
413  }
414  echo '</p>';
415  }
416 
417  }//end paintDownloadFields()
418 
419 
430  function paintDownloadButton(&$asset, &$o, $prefix)
431  {
432  if (!$asset->writeAccess('attributes')) {
433  $o->note(translate('online_quiz_form_submission_lock_required'));
434  return FALSE;
435  }
436 
437  // explanation for onClick for the Download button, there is some trickery involved here >:)
438  // - set export switch to 1 = "ON"
439  // - submit form (automatically sets SQ_FORM_SUBMITTED) - we're still here though, as the
440  // browser will be sent through the CSV/XML file and it will be offered to save - not display
441  // (DEPENDS on browser - CSV should be offered to save, XML could be intercepted by browser!)
442  // - unset SQ_FORM_SUBMITTED so the form can still be submitted via Commit
443  // - set export switch to 0 = "OFF" so Commit doesn't try to save a file either
444  // - return true for the event as per JS standard
445 
446  echo normal_button($prefix.'_export', translate('download_file'), 'this.form.'.$prefix.'_export_switch.value = 1; this.form.submit(); SQ_FORM_SUBMITTED = false; this.form.'.$prefix.'_export_switch.value = 0; return true;');
447 
448  }//end paintDownloadButton()
449 
450 
461  function paintSubmissionDateRange(&$asset, &$o, $prefix)
462  {
463  $parameters = Array(
464  'min' => '2003-01-01 00:00:00',
465  'max' => ts_iso8601(time()),
466  'allow_circa' => '0',
467  'show' => Array('y', 'm', 'd'),
468  'null' => Array(),
469  'style' => Array(
470  'y' => 's',
471  'm' => 's',
472  'd' => 's',
473  ),
474  );
475 
476  $parameters['print_format'] = 'j M Y';
477 
478  $from_value = isset($_POST[$prefix.'_fromvalue']) ? ts_iso8601(mktime(0,0,0,$_POST[$prefix.'_fromvalue']['m'],$_POST[$prefix.'_fromvalue']['d'],$_POST[$prefix.'_fromvalue']['y'])) : date('Y-m-d',time()-7*86400).' --:--:--';
479  $to_value = isset($_POST[$prefix.'_tovalue']) ? ts_iso8601(mktime(0,0,0,$_POST[$prefix.'_tovalue']['m'],$_POST[$prefix.'_tovalue']['d'],$_POST[$prefix.'_tovalue']['y'])) : date('Y-m-d').' --:--:--';
480 
481  $from = new Datetime_Field($prefix.'_from', $from_value, $parameters);
482  $to = new Datetime_Field($prefix.'_to', $to_value, $parameters);
483 
484  $from->printField();
485  echo ' '.translate('to').' ';
486  $to->printField();
487 
488  return TRUE;
489 
490  }//end paintSubmissionDateRange()
491 
492 
503  function paintSubmissionCount(&$asset, &$o, $prefix)
504  {
505  $num_per_page = array_get_index($_REQUEST, $prefix.'_per_page', 50);
506  if ($num_per_page < 1) $num_per_page = 50;
507 
508  text_box($prefix.'_per_page', $num_per_page, 3);
509 
510  }//end paintSubmissionCount()
511 
512 
523  function paintSubmissionList(&$asset, &$o, $prefix)
524  {
525  $write_access = $asset->writeAccess('links');
526  $expand_list = isset($_POST[$prefix.'_expand']) ? $_POST[$prefix.'_expand'] : Array();
527  $expand_sections = isset($_POST[$prefix.'_expand_sections']) ? $_POST[$prefix.'_expand_sections'] : Array();
528  $num_subs = 0;
529 
530  // grab the number of assets per page, defaulting to 50 at a time
531  $num_per_page = array_get_index($_REQUEST, $prefix.'_per_page', 50);
532  if ($num_per_page < 1) $num_per_page = 50;
533 
534  $submission_offset = array_get_index($_REQUEST, $prefix.'_submission_offset', 0);
535 
536  $from_value = isset($_POST[$prefix.'_fromvalue']) ? ts_iso8601(mktime(0,0,0,$_POST[$prefix.'_fromvalue']['m'],$_POST[$prefix.'_fromvalue']['d'],$_POST[$prefix.'_fromvalue']['y'])) : date('Y-m-d',time()-7*86400).' --:--:--';
537  $to_value = isset($_POST[$prefix.'_tovalue']) ? ts_iso8601(mktime(0,0,0,$_POST[$prefix.'_tovalue']['m'],$_POST[$prefix.'_tovalue']['d'],$_POST[$prefix.'_tovalue']['y'])) : date('Y-m-d').' --:--:--';
538 
539  $from_value = iso8601_date_component($from_value).' 00:00:00';
540  $to_value = iso8601_date_component($to_value).' 23:59:59';
541 
542  // convert the ISO times to time stamps but manually because we can't be sure
543  // about the h:m:s section of the above times
544  $from_ts = mktime(0,0,0,$from_value[1],$from_value[2],$from_value[0]);
545  $to_ts = mktime(23,59,59,$to_value[1],$to_value[2],$to_value[0]);
546 
547  $sql = 'SELECT
548  a.assetid, a.created_userid, a.created
549  FROM
550  ('.SQ_TABLE_RUNNING_PREFIX.'ast a
551  JOIN '.SQ_TABLE_RUNNING_PREFIX.'ast_typ_inhd i ON a.type_code = i.type_code)
552  JOIN '.SQ_TABLE_RUNNING_PREFIX.'ast_lnk l
553  ON l.minorid = a.assetid';
554 
555  $count_sql = 'SELECT
556  count(*)
557  FROM
558  ('.SQ_TABLE_RUNNING_PREFIX.'ast a
559  JOIN '.SQ_TABLE_RUNNING_PREFIX.'ast_typ_inhd i ON a.type_code = i.type_code)
560  JOIN '.SQ_TABLE_RUNNING_PREFIX.'ast_lnk l
561  ON l.minorid = a.assetid';
562 
563  $sub_folder = $asset->getSubmissionsFolder();
564 
565  $db = Dal::getDb();
566 
567  $ts_from_fragment = db_extras_todate(MatrixDAL::getDbType(), ':from_date', FALSE);
568  $ts_to_fragment = db_extras_todate(MatrixDAL::getDbType(), ':to_date', FALSE);
569 
570  $where = 'l.majorid IN (:assetid, :subfolder_assetid)
571  AND i.inhd_type_code = :inhd_type_code
572  AND a.created BETWEEN '.$ts_from_fragment.'
573  AND '.$ts_to_fragment;
574 
575  $where = $GLOBALS['SQ_SYSTEM']->constructRollbackWhereClause($where, 'a');
576  $where = $GLOBALS['SQ_SYSTEM']->constructRollbackWhereClause($where, 'i');
577  $where = $GLOBALS['SQ_SYSTEM']->constructRollbackWhereClause($where, 'l');
578 
579  // grab the number of assets
580  $asset_count = 0;
581  try {
582  $query = MatrixDAL::preparePdoQuery($count_sql.$where);
583  MatrixDAL::bindValueToPdo($query, 'assetid', $asset->id);
584  MatrixDAL::bindValueToPdo($query, 'subfolder_assetid', $sub_folder->id);
585  MatrixDAL::bindValueToPdo($query, 'inhd_type_code', 'online_quiz_submission');
586  MatrixDAL::bindValueToPdo($query, 'from_date', $from_value);
587  MatrixDAL::bindValueToPdo($query, 'to_date', $to_value);
588  $asset_count = MatrixDAL::executePdoOne($query);
589  } catch (Exception $e) {
590  throw new Exception($e.getMessage());
591  }
592 
593  $num_pages = ceil($asset_count / $num_per_page);
594 
595 
596  if (($submission_offset % $num_per_page) != 0) {
597  $submission_offset = $submission_offset - ($submission_offset % $num_per_page);
598  }
599 
600  if ($submission_offset < 0) $submission_offset = 0;
601 
602  if ($submission_offset >= $asset_count) {
603  $submission_offset = ($num_pages - 1) * $num_per_page;
604  }
605 
606  $sql = $sql.$where.' ORDER BY a.created DESC';
607 
608  $sql = db_extras_modify_limit_clause($sql, MatrixDAL::getDbType(),$num_per_page, $submission_offset);
609  if ($asset_count == 0) {
610  ?><p><i><?php echo translate('online_quiz_no_submissions_during_period') ?></i></p><?php
611  } else {
612  ?><style type="text/css">
613  td.sq-form-sub {
614  padding-top: 0px;
615  }
616  .sq-form-sub table.sq-backend-table {
617  border-top: 0px;
618  margin: 0 8px 8px 8px;
619  }
620  .sq-form-sub table.sq-backend-table th {
621  font-weight: normal;
622  text-decoration: italic;
623  }
624  table.sq-backend-table tr td.sq-form-sub-header {
625  background-color: #666;
626  color: #fff;
627  font-size: 11px;
628  }
629  </style>
630  <script type="text/javascript"><!--
631  function sq_set_check_all(form, prefix, value) {
632  set_els = form.elements[prefix];
633 
634  if (set_els.length) {
635  for (k = 0; k < set_els.length; k++) {
636  set_els[k].checked = value;
637  }
638  } else {
639  set_els.checked = value;
640  }
641  }
642 
643  function sq_test_check_all(form, prefix, set_el) {
644  test_els = form.elements[prefix];
645  set_el = form.elements[set_el];
646 
647  if (test_els.length) {
648  test = true;
649  for (k = 0; k < test_els.length; k++) {
650  if (!test_els[k].checked) {
651  test = false;
652  break;
653  }
654  }
655  } else {
656  test = test_els.checked;
657  }
658 
659  set_el.checked = test;
660  }
661  //--></script>
662  <table class="sq-backend-table">
663  <tr>
664  <td class="sq-form-sub-header" colspan="2"><b><?php
665  hidden_field($prefix.'_submission_offset', $submission_offset);
666  if ($submission_offset > 0) {
667  ?><a title="<?php echo translate('online_quiz_submissions_go_to_first') ?>" style="text-decoration: none; color: #fff" href="#" onClick="Javascript: set_hidden_field('<?php echo $prefix ?>_submission_offset', '0'); set_hidden_field('process_form', '0'); submit_form(); return false;"><?php
668  } else {
669  ?><span title="<?php echo translate('online_quiz_cannot_go_further_back') ?>" style="color: #333"><?php
670  }
671  ?>
672  &lt;&lt;
673  <?php
674  if ($submission_offset > 0) {
675  ?></a><?php
676  } else {
677  ?></span><?php
678  }
679  ?> &nbsp; &nbsp; <?php
680  if ($submission_offset > 0) {
681  ?><a title="<?php echo translate('online_quiz_submissions_go_to_previous') ?>" style="text-decoration: none; color: #fff" href="#" onClick="Javascript: set_hidden_field('<?php echo $prefix ?>_submission_offset', '<?php echo $submission_offset - $num_per_page; ?>'); set_hidden_field('process_form', '0'); submit_form(); return false;"><?php
682  } else {
683  ?><span title="<?php echo translate('online_quiz_cannot_go_further_back') ?>" style="color: #333"><?php
684  }
685  ?>
686  &lt;
687  <?php
688  if ($submission_offset > 0) {
689  ?></a><?php
690  } else {
691  ?></span><?php
692  }
693  ?>
694  &nbsp; &nbsp; <?php echo translate('page_number', round(($submission_offset + $num_per_page) / $num_per_page), ceil($asset_count / $num_per_page)); ?> &nbsp; &nbsp;
695  <?php
696  if (($submission_offset + $num_per_page) < $asset_count) {
697  ?><a title="<?php echo translate('online_quiz_submissions_go_to_next') ?>" style="text-decoration: none; color: #fff" href="#" onClick="Javascript: set_hidden_field('<?php echo $prefix ?>_submission_offset', '<?php echo $submission_offset + $num_per_page; ?>'); set_hidden_field('process_form', '0'); submit_form(); return false;"><?php
698  } else {
699  ?><span title="<?php echo translate('online_quiz_cannot_go_further_forward') ?>" style="color: #333"><?php
700  }
701  ?>
702  &gt;
703  <?php
704  if (($submission_offset + $num_per_page) < $asset_count) {
705  ?></a><?php
706  } else {
707  ?></span><?php
708  }
709  ?> &nbsp; &nbsp; <?php
710  if (($submission_offset + $num_per_page) < $asset_count) {
711  ?><a title="<?php echo translate('online_quiz_submissions_go_to_last') ?>" style="text-decoration: none; color: #fff" href="#" onClick="Javascript: set_hidden_field('<?php echo $prefix ?>_submission_offset', '<?php echo ($num_pages - 1) * $num_per_page; ?>'); set_hidden_field('process_form', '0'); submit_form(); return false;"><?php
712  } else {
713  ?><span title="<?php echo translate('online_quiz_cannot_go_further_forward') ?>" style="color: #333"><?php
714  }
715  ?>
716  &gt;&gt;
717  <?php
718  if (($submission_offset + $num_per_page) < $asset_count) {
719  ?></a><?php
720  } else {
721  ?></span><?php
722  }
723  ?></b>
724  </td>
725  <td class="sq-form-sub-header" colspan="5" align="right"><?php echo translate('online_quiz_submissions_during_period', $submission_offset + 1, min($asset_count, $submission_offset + $num_per_page), $asset_count) ?>
726  </td>
727  </tr>
728  <tr>
729  <th>
730  <?php echo translate('asset_id') ?>
731  </th>
732  <th>
733  <?php echo translate('submission_time') ?>
734  </th>
735  <th>
736  <?php echo translate('user') ?>
737  </th>
738  <th>
739  <?php echo translate('online_quiz_score') ?>
740  </th>
741  <th>
742  <input type="checkbox" name="<?php echo $prefix ?>_expand_all" value="" onclick="sq_set_check_all(this.form, '<?php echo $prefix ?>_expand[]', this.checked);"> <?php echo translate('expand_question') ?>
743  </th>
744  <?php
745  if ($write_access) {
746  ?>
747  <th>
748  <input type="checkbox" name="<?php echo $prefix ?>_delete_all" value="" onclick="sq_set_check_all(this.form, '<?php echo $prefix ?>_delete[]', this.checked);"> <?php echo translate('delete_question') ?>
749  </th>
750  <?php
751  }
752  ?>
753  <th>&nbsp;</th>
754  </tr>
755  <?php
756  // For memory reasons, we are going to fetch this one row at a time
757  // because we could be displaying a lot on this page
758  $result = NULL;
759  try {
760  $_query = MatrixDAL::preparePdoQuery($sql);
761  MatrixDAL::bindValueToPdo($_query, 'assetid', $asset->id);
762  MatrixDAL::bindValueToPdo($_query, 'subfolder_assetid', $sub_folder->id);
763  MatrixDAL::bindValueToPdo($_query, 'inhd_type_code', 'online_quiz_submission');
764  MatrixDAL::bindValueToPdo($_query, 'from_date', $from_value);
765  MatrixDAL::bindValueToPdo($_query, 'to_date', $to_value);
766  $result = MatrixDAL::executePdoAssoc($_query);
767  } catch (Exception $e) {
768  throw new Exception($e->getMessage());
769  }
770 
771  foreach ($result as $k => $asset_info) {
772  $assetid = $asset_info['assetid'];
773 
774  // time is good, load me up
775  $sub_asset = $GLOBALS['SQ_SYSTEM']->am->getAsset($assetid);
776  $sub_user = $asset_info['created_userid'];
777  $sub_time = date('d M Y H:i:s', strtotime($asset_info['created']));
778  $sub_expanded = array_search($assetid, $expand_list) !== FALSE;
779  $num_subs++;
780 
781  if ($num_subs > $num_per_page) break;
782  ?>
783  <tr<?php
784  echo ($sub_expanded) ? ' class="alt"' : '';
785  ?>>
786  <td>
787  <?php echo $assetid ?>
788  </td>
789  <td>
790  <?php echo $sub_time ?>
791  </td>
792  <td>
793  <?php
794  $valid_user = FALSE;
795  if (!empty($sub_user)) {
796  $sub_user_asset = $GLOBALS['SQ_SYSTEM']->am->getAsset($sub_user);
797  if (!empty($sub_user_asset)) {
798  echo get_asset_tag_line($sub_user);
799  $valid_user = TRUE;
800  }
801  }
802  if (!$valid_user) {
803  ?><i><?php echo translate('online_quiz_no_logged_in_user'); ?></i><?php
804  }
805  ?>
806  </td>
807  <td> <?php echo $sub_asset->getScore(); ?></td>
808  <td>
809  <input type="checkbox" name="<?php echo $prefix ?>_expand[]" value="<?php echo $assetid ?>" <?php if ($sub_expanded) echo ' checked="checked"'; ?> onclick="sq_test_check_all(this.form, '<?php echo $prefix ?>_expand[]', '<?php echo $prefix ?>_expand_all');">
810  </td>
811  <?php
812  if ($write_access) {
813  ?>
814  <td>
815  <input type="checkbox" name="<?php echo $prefix ?>_delete[]" value="<?php echo $assetid ?>" onclick="sq_test_check_all(this.form, '<?php echo $prefix ?>_delete[]', '<?php echo $prefix ?>_delete_all');">
816  </td>
817  <?php
818  }
819  ?>
820  <td>[ <a href="<?php echo $sub_asset->getBackendHref(); ?>"><?php echo translate('view') ?></a> ]</td>
821  </tr>
822  <?php
823  // display only if expanded
824  if ($sub_expanded) {
825  ?>
826  <tr>
827  <td colspan="6" class="sq-form-sub">
828  <table class="sq-backend-table">
829  <tr>
830  <?php
831  $i = 0;
832  $incl_user_details = in_array('__user_details__',$expand_sections) ? TRUE : FALSE;
833  $incl_quiz_responses = in_array('__quiz_responses__', $expand_sections) ? TRUE : FALSE;
834 
835  $elements = $sub_asset->getSummary($incl_user_details, $incl_quiz_responses);
836  if (count($elements) % 2 != 0) {
837  $elements[] = Array('name' => '', 'answer' => '');
838  }
839  foreach ($elements as $element) {
840  $i++;
841  ?>
842  <th><?php echo $element['name'] ?>:</th>
843  <td><?php echo htmlspecialchars($element['answer']); ?></td>
844  <?php
845  if (($i < count($elements)) && ($i % 2 == 0)) {
846  ?>
847  </tr>
848  <tr>
849  <?php
850  }
851  }//end foreach elemnent
852  ?>
853  </tr>
854  </table>
855  </td>
856  </tr>
857  <?php
858  }//end if expanded
859  }//end while submission
860  ?>
861  </table>
862  <script type="text/javascript"><!--
863  sq_test_check_all(document.main_form, '<?php echo $prefix ?>_expand[]', '<?php echo $prefix ?>_expand_all');
864  //--></script>
865  <?php
866  }//end else
867 
868 
869  return TRUE;
870 
871  }//end paintSubmissionList()
872 
873 
884  function processSubmissionList(&$asset, &$o, $prefix)
885  {
886  $delete_list = isset($_POST[$prefix.'_delete']) ? $_POST[$prefix.'_delete'] : Array();
887  if (empty($delete_list)) return FALSE;
888 
889  $GLOBALS['SQ_SYSTEM']->changeDatabaseConnection('db2');
890  $GLOBALS['SQ_SYSTEM']->doTransaction('BEGIN');
891 
892  // acquire the links lock on the form
893  if (!$GLOBALS['SQ_SYSTEM']->am->acquireLock($asset->id, 'links')) {
894  $GLOBALS['SQ_SYSTEM']->doTransaction('ROLLBACK');
895  $GLOBALS['SQ_SYSTEM']->restoreDatabaseConnection();
896  return FALSE;
897  }
898 
899  foreach ($delete_list as $delete_assetid) {
900  // is the assetid a valid one?
901  if (!assert_valid_assetid($delete_assetid, '', FALSE, FALSE)) {
902  $GLOBALS['SQ_SYSTEM']->doTransaction('ROLLBACK');
903  $GLOBALS['SQ_SYSTEM']->restoreDatabaseConnection();
904  return FALSE;
905  }
906 
907  // acquire the links lock on the submission to delete
908  if (!$GLOBALS['SQ_SYSTEM']->am->acquireLock($delete_assetid, 'links')) {
909  $GLOBALS['SQ_SYSTEM']->doTransaction('ROLLBACK');
910  $GLOBALS['SQ_SYSTEM']->restoreDatabaseConnection();
911  return FALSE;
912  }
913  $submissions_folder = $asset->getSubmissionsFolder();
914  $submission_link = $GLOBALS['SQ_SYSTEM']->am->getLinkByAsset($submissions_folder->id, $delete_assetid, SQ_LINK_TYPE_3);
915  if (!$submission_link) {
916  $GLOBALS['SQ_SYSTEM']->doTransaction('ROLLBACK');
917  $GLOBALS['SQ_SYSTEM']->restoreDatabaseConnection();
918  return FALSE;
919  } else {
920  if (!$submissions_folder->deleteLink($submission_link['linkid'])) {
921  $GLOBALS['SQ_SYSTEM']->doTransaction('ROLLBACK');
922  $GLOBALS['SQ_SYSTEM']->restoreDatabaseConnection();
923  return FALSE;
924  }
925  }
926 
927  // release the links lock
928  if (!$GLOBALS['SQ_SYSTEM']->am->releaseLock($delete_assetid, 'links')) {
929  $GLOBALS['SQ_SYSTEM']->doTransaction('ROLLBACK');
930  $GLOBALS['SQ_SYSTEM']->restoreDatabaseConnection();
931  return FALSE;
932  }
933  }//end foreach
934  // now release the links lock on the form itself
935  if (!$GLOBALS['SQ_SYSTEM']->am->releaseLock($asset->id, 'links')) {
936  $GLOBALS['SQ_SYSTEM']->doTransaction('ROLLBACK');
937  $GLOBALS['SQ_SYSTEM']->restoreDatabaseConnection();
938  return FALSE;
939  }
940 
941  $GLOBALS['SQ_SYSTEM']->doTransaction('COMMIT');
942  $GLOBALS['SQ_SYSTEM']->restoreDatabaseConnection();
943 
944  return TRUE;
945 
946  }//end processSubmissionList()
947 
948 
962  function processDownloadButton(&$asset, &$o, $prefix)
963  {
964  $export_button_pressed = array_get_index($_POST, $prefix.'_export_switch');
965  if (is_null($export_button_pressed)) return TRUE;
966 
967  $export_type = array_get_index($_POST, $prefix.'_export_format', '');
968  $export_delimiter = array_get_index($_POST, $prefix.'_delimiter', '');
969 
970  // Grab the asset IDs of the export fields as the value of the array. Must select some fields for export to proceed
971  if (isset($_POST[$prefix.'_export_fields'])) {
972  $export_fields = $_POST[$prefix.'_export_fields'];
973 
974  if (!empty($export_fields)) {
975  switch ($export_type) {
976  case 'csv':
977  $this->processExportCSV($asset, $o, $prefix, $export_fields, TRUE, $export_delimiter);
978  break;
979 
980  case 'csv_nhr':
981  $this->processExportCSV($asset, $o, $prefix, $export_fields, FALSE, $export_delimiter);
982  break;
983  }
984  }
985  }
986 
987  return TRUE;
988 
989  }//end processDownloadButton()
990 
991 
1007  function processExportCSV(&$asset, &$o, $prefix, $export_fields=Array(), $header_row=TRUE, $delimiter=',')
1008  {
1009  require_once SQ_FUDGE_PATH.'/csv/csv.inc';
1010  $csv = new CSV();
1011  $csv->setFilename('submission_log.csv');
1012  $csv->setDeliminator($delimiter);
1013 
1014  // get the from and to values
1015  $from_value = isset($_POST[$prefix.'_export_fromvalue']) ? ts_iso8601(mktime(0,0,0,$_POST[$prefix.'_export_fromvalue']['m'],$_POST[$prefix.'_export_fromvalue']['d'],$_POST[$prefix.'_export_fromvalue']['y'])) : '---------- --:--:--';
1016  $to_value = isset($_POST[$prefix.'_export_tovalue']) ? ts_iso8601(mktime(0,0,0,$_POST[$prefix.'_export_tovalue']['m'],$_POST[$prefix.'_export_tovalue']['d'],$_POST[$prefix.'_export_tovalue']['y'])) : '---------- --:--:--';
1017 
1018  $from_value = explode('-',iso8601_date_component($from_value));
1019  $to_value = explode('-',iso8601_date_component($to_value));
1020 
1021  // convert the ISO times to time stamps but manually because we can't be sure
1022  // about the h:m:s section of the above times
1023  $from_ts = mktime(0,0,0,$from_value[1],$from_value[2],$from_value[0]);
1024  $to_ts = mktime(23,59,59,$to_value[1],$to_value[2],$to_value[0]);
1025 
1026  $logs = Array();
1027  $headers = Array();
1028 
1029  $export_time_field = in_array('__time__', $export_fields);
1030  $export_user_field = in_array('__user__', $export_fields);
1031  $export_ipaddress_field = in_array('__ipaddress__', $export_fields);
1032  $export_score_field = in_array('__score__', $export_fields);
1033 
1034  if ($export_time_field) {
1035  $headers['__time__'] = translate('submission_time');
1036  }
1037  if ($export_user_field) {
1038  $headers['__user__'] = translate('online_quiz_user_id');
1039  }
1040  if ($export_ipaddress_field) {
1041  $headers['__ipaddress__'] = translate('online_quiz_ip_address');
1042  }
1043  if ($export_score_field) {
1044  $headers['__score__'] = translate('online_quiz_score');
1045  }
1046 
1047  $sub_folder = $asset->getSubmissionsFolder();
1048 
1049  $base_sql = 'SELECT
1050  a.assetid, a.type_code, a.created, a.created_userid
1051  FROM
1052  ('.SQ_TABLE_RUNNING_PREFIX.'ast a JOIN '.SQ_TABLE_RUNNING_PREFIX.'ast_typ_inhd i ON a.type_code = i.type_code)
1053  JOIN '.SQ_TABLE_RUNNING_PREFIX.'ast_lnk l
1054  ON l.minorid = a.assetid';
1055 
1056  $where = 'l.majorid IN ('.MatrixDAL::quote($asset->id).', '.MatrixDAL::quote($sub_folder->id).') AND i.inhd_type_code = '.MatrixDAL::quote('online_quiz_submission').' AND a.created BETWEEN '.MatrixDAL::quote(ts_iso8601($from_ts)).' AND '.MatrixDAL::quote(ts_iso8601($to_ts));
1057 
1058  $where = $GLOBALS['SQ_SYSTEM']->constructRollbackWhereClause($where, 'a');
1059  $where = $GLOBALS['SQ_SYSTEM']->constructRollbackWhereClause($where, 'i');
1060  $where = $GLOBALS['SQ_SYSTEM']->constructRollbackWhereClause($where, 'l');
1061 
1062  // This could be a large download, however DAL does not easily support
1063  // row by row fetching, so we will do it in chunks of 1000, or however
1064  // many we get back. If we don't get that many, we will continue to
1065  // query until there are no more, to pick up any additional
1066  // submissions made since the first query was made.
1067  $offset = 0;
1068  $chunk_size = 1000;
1069 
1070  while (TRUE) {
1071  // Get the current limited query
1072  $sql = db_extras_modify_limit_clause($base_sql.$where, MatrixDAL::getDbType(), $chunk_size, $offset);
1073  $result = MatrixDAL::executeSqlAssoc($sql);
1074 
1075  // If no further results, we are done.
1076  if (count($result) == 0) break;
1077 
1078  foreach ($result as $asset_info) {
1079  $assetid = $asset_info['assetid'];
1080  $type_code = $asset_info['type_code'];
1081 
1082  $create_time = strtotime($asset_info['created']);
1083 
1084  $sub_asset = $GLOBALS['SQ_SYSTEM']->am->getAsset($assetid, $type_code);
1085  if (!$sub_asset->attr('complete')) continue;
1086 
1087  // get the submission ip
1088  $ipaddress = $sub_asset->getIP();
1089  $score = $sub_asset->getScore();
1090 
1091  // get the summary
1092  $logs[$assetid] = Array();
1093 
1094  if ($export_time_field) {
1095  $logs[$assetid]['__time__'] = date('Y-m-d H:i:s', $create_time);
1096  }
1097  if ($export_user_field) {
1098  $logs[$assetid]['__user__'] = $asset_info['created_userid'];
1099  }
1100  if ($export_ipaddress_field) {
1101  $logs[$assetid]['__ipaddress__'] = $ipaddress;
1102  }
1103  if ($export_score_field) {
1104  $logs[$assetid]['__score__'] = $score;
1105  }
1106 
1107  $submission_summary = $sub_asset->getSummary();
1108 
1109  // Export full Question Text and Question Answer Text
1110  foreach ($submission_summary as $question_id => $details) {
1111  // Now we're only interested in fields that have been specified for export
1112  if (in_array($question_id, $export_fields)) {
1113  if (!isset($headers[$question_id])) {
1114  $headers[$question_id] = $details['name'];
1115  }
1116  $logs[$assetid][$question_id] = $details['answer'];
1117  }
1118  }
1119 
1120  }//end foreach
1121 
1122  // Advance the chains along, and prepare to get more records
1123  $offset =+ count($result);
1124 
1125  }//end while - there are more records
1126 
1127  if ($header_row) $csv->setFieldHeaders($headers);
1128 
1129  $csv->setValues($logs);
1130 
1131  // export with keyed fields
1132  $csv->export(TRUE);
1133  exit(0);
1134 
1135  return TRUE;
1136 
1137  }//end processExportCSV()
1138 
1139 
1150  function paintQuestionPoolSetup(&$asset, &$o, $prefix)
1151  {
1152  $write_access = $asset->writeAccess('attributes');
1153  // get existing root links (pools)
1154  $root_links = $GLOBALS['SQ_SYSTEM']->am->getLinks($asset->id, SQ_LINK_NOTICE, '', FALSE, 'major', 'root');
1155  $pool_setup = $asset->attr('question_pool_setup');
1156 
1157  ?>
1158  <table class="sq-backend-table">
1159  <tr>
1160  <td class="sq-backend-table-header" >
1161  <?php echo translate('online_quiz_pool_node'); ?>
1162  </td>
1163  <td class="sq-backend-table-header">
1164  <?php echo translate('online_quiz_pool_size'); ?>
1165  </td>
1166  <td class="sq-backend-table-header">
1167  <?php echo translate('online_quiz_pool_retries_per_q'); ?>
1168  </td>
1169  <td class="sq-backend-table-header">
1170  <?php echo translate('online_quiz_pool_order'); ?>
1171  </td>
1172  </tr>
1173  <?php
1174  $order = 1;
1175  foreach ($root_links as $link){
1176  ?>
1177  <tr>
1178  <td class="sq-backend-table-cell">
1179  <?php
1180  echo get_asset_tag_line($link['minorid'], 'details');
1181  ?>
1182  </td>
1183  <td class="sq-backend-table-cell">
1184  <?php
1185  $size = (!empty($pool_setup[$link['minorid']]['size'])) ? $pool_setup[$link['minorid']]['size'] : 0;
1186  if ($write_access){
1187  text_box($prefix.'_size_'.$link['minorid'], $size);
1188  } else {
1189  echo $size;
1190  }
1191  ?>
1192  </td>
1193  <td class="sq-backend-table-cell">
1194  <?php
1195  $retries = (!empty($pool_setup[$link['minorid']]['retries'])) ? $pool_setup[$link['minorid']]['retries'] : 0;
1196  if ($write_access){
1197  text_box($prefix.'_retries_'.$link['minorid'], $retries);
1198  } else {
1199  echo $retries;
1200  }
1201  ?>
1202  </td>
1203  <td class="sq-backend-table-cell">
1204  <?php
1205  if ($write_access){
1206  text_box($prefix.'_order_'.$link['minorid'], $order);
1207  } else {
1208  echo $order;
1209  }
1210  ?>
1211  </td>
1212  </tr>
1213  <?php
1214  $order++;
1215  }
1216  ?>
1217  </table>
1218  <?php
1219  hidden_field($prefix.'_interactive_mode', '1');
1220 
1221  return TRUE;
1222 
1223  }//end paintQuestionPoolSetup()
1224 
1225 
1236  function processQuestionPoolSetup(&$asset, &$o, $prefix)
1237  {
1238  if (!$asset->writeAccess('attributes')) return FALSE;
1239  if (!isset($_POST[$prefix.'_interactive_mode'])) return TRUE;
1240 
1241  //adjust the order first
1242  $root_links = $GLOBALS['SQ_SYSTEM']->am->getLinks($asset->id, SQ_LINK_NOTICE, '', FALSE, 'major', 'root');
1243  foreach ($root_links as $link){
1244  $order = (isset($_POST[$prefix.'_order_'.$link['minorid']])) ? (int)$_POST[$prefix.'_order_'.$link['minorid']] : $link['sort_order'];
1245  $GLOBALS['SQ_SYSTEM']->am->updateLink($link['linkid'], $link['link_type'], $link['value'], $order, $link['locked']);
1246  }
1247 
1248  $pool_setup = Array();
1249  $root_links = $GLOBALS['SQ_SYSTEM']->am->getLinks($asset->id, SQ_LINK_NOTICE, '', FALSE, 'major', 'root');
1250  foreach ($root_links as $link){
1251  $retries = (isset($_POST[$prefix.'_retries_'.$link['minorid']])) ? (int)$_POST[$prefix.'_retries_'.$link['minorid']] : 0;
1252  $size = (isset($_POST[$prefix.'_size_'.$link['minorid']])) ? (int)$_POST[$prefix.'_size_'.$link['minorid']] : 0;
1253  $children = $GLOBALS['SQ_SYSTEM']->am->getChildren($link['minorid'], 'online_quiz_question_multichoice', TRUE);
1254  if (($size + ($size*$retries)) > (count($children))){
1255  trigger_localised_error('CMS0113', E_USER_WARNING, $link['minorid']);
1256  }
1257 
1258  $pool_setup[$link['minorid']] = Array (
1259  'retries' => $retries,
1260  'size' => $size,
1261  );
1262  }
1263 
1264  $asset->setAttrValue('question_pool_setup', $pool_setup);
1265  $asset->saveAttributes();
1266 
1267  return TRUE;
1268 
1269  }//end processQuestionPoolSetup()
1270 
1271 
1282  function paintExpandSections(&$asset, &$o, $prefix)
1283  {
1284 
1285  $expand_sections = isset($_POST[$prefix.'_expand_sections']) ? $_POST[$prefix.'_expand_sections'] : Array();
1286 
1287  //default is both checked and if you uncheck both, they'll be rechecked
1288  $checked = ($expand_sections) ? in_array('__user_details__', $expand_sections) : TRUE;
1289  echo check_box($prefix.'_expand_sections[]', '__user_details__', $checked).'User Details Form Questions<br/>';
1290  $checked = ($expand_sections) ? in_array('__quiz_responses__', $expand_sections) : TRUE;
1291  echo check_box($prefix.'_expand_sections[]', '__quiz_responses__', $checked).'Quiz Questions<br/>';
1292 
1293  }//end paintExpandSections()
1294 
1295 
1306  function paintQuestionOptionFormat(&$asset, &$o, $prefix)
1307  {
1308  $write_access = $asset->writeAccess('attributes');
1309 
1310  if ($write_access) {
1311  text_area($prefix.'_question_option_format', $asset->attr('question_option_format'), 0, 0, 0, 'style="width: 300px; height: 100px;"');
1312  } else {
1313  echo htmlentities($asset->attr('question_option_format'));
1314  }
1315 
1316  return TRUE;
1317 
1318  }//end paintQuestionOptionFormat()
1319 
1320 
1331  function processQuestionOptionFormat(&$asset, &$o, $prefix)
1332  {
1333  if (!$asset->writeAccess('attributes')) return FALSE;
1334 
1335  if (isset($_REQUEST[$prefix.'_question_option_format']) === TRUE) {
1336  $question_option_format = array_get_index($_REQUEST, $prefix.'_question_option_format', '');
1337  $asset->setAttrValue('question_option_format', trim($question_option_format));
1338  }
1339 
1340  return TRUE;
1341 
1342  }//end processQuestionOptionFormat()
1343 
1344 
1354  function hasAttributeWriteAccess(&$asset, &$o)
1355  {
1356  return $asset->writeAccess('attributes');
1357 
1358  }//end hasAttributeWriteAccess()
1359 
1360 
1369  function isListingMode(&$asset)
1370  {
1371  return ($asset->attr('interactive_mode')) ? FALSE : TRUE;
1372 
1373  }//end isListingMode()
1374 
1375 
1384  function isInteractiveMode(&$asset)
1385  {
1386  return ($asset->attr('interactive_mode')) ? TRUE : FALSE;
1387 
1388  }//end isInteractiveMode()
1389 
1390 
1391 }//end class
1392 
1393 ?>