1: <?php
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23: 24: 25: 26: 27: 28: 29:
30:
31: 32: 33: 34: 35:
36: function F_encodeOMRTestData($data)
37: {
38: $str = serialize($data);
39: $str = gzcompress($str, 9);
40: $str = base64_encode($str);
41: $str = urlencode($str);
42: return $str;
43: }
44:
45: 46: 47: 48: 49:
50: function F_decodeOMRTestData($str)
51: {
52: if (empty($str)) {
53: return false;
54: }
55: $data = $str;
56: $data = urldecode($data);
57: $data = base64_decode($data);
58: $data = gzuncompress($data);
59: $data = unserialize($data);
60: return $data;
61: }
62:
63: 64: 65: 66: 67: 68:
69: function F_decodeOMRTestDataQRCode($image)
70: {
71: require_once('../config/tce_config.php');
72: if (empty($image)) {
73: return false;
74: }
75: $command = K_OMR_PATH_ZBARIMG.' --raw -Sdisable -Sqrcode.enable -q '.escapeshellarg($image);
76: $str = exec($command);
77: return F_decodeOMRTestData($str);
78: }
79:
80: 81: 82: 83: 84: 85:
86: function F_decodeOMRPage($image)
87: {
88: require_once('../config/tce_config.php');
89:
90: $command = K_OMR_PATH_ZBARIMG.' --raw -Sdisable -Scode128.enable -q '.escapeshellarg($image);
91: $qstart = exec($command);
92: $qstart = intval($qstart);
93: if ($qstart == 0) {
94: return false;
95: }
96: $img = new Imagick();
97: $img->readImage($image);
98: $imginfo = $img->identifyImage();
99: if ($imginfo['type'] == 'TrueColor') {
100:
101: $img->separateImageChannel(Imagick::CHANNEL_RED);
102: } else {
103:
104: $img->modulateImage(100, 0, 100);
105: }
106:
107: $w = $imginfo['geometry']['width'];
108: $h = $imginfo['geometry']['height'];
109: if ($h > $w) {
110:
111: $y = round(($h - $w) / 2);
112: $img->cropImage($w, $w, 0, $y);
113: $img->setImagePage(0, 0, 0, 0);
114: }
115: $img->normalizeImage(Imagick::CHANNEL_ALL);
116: $img->enhanceImage();
117: $img->despeckleImage();
118: $img->blackthresholdImage('#808080');
119: $img->whitethresholdImage('#808080');
120: $img->trimImage(85);
121: $img->deskewImage(15);
122: $img->trimImage(85);
123: $img->resizeImage(1028, 1052, Imagick::FILTER_CUBIC, 1);
124: $img->setImagePage(0, 0, 0, 0);
125:
126:
127: $blkw = 16;
128:
129: $scol = 106;
130:
131: $srow = 49;
132:
133: $dcol = 75.364;
134:
135: $dtf = 25;
136:
137: $drow = 32.38;
138:
139: $imgtmp = clone $img;
140: $imgtmp->cropImage(1028, 10, 0, 10);
141: $imgtmp->setImagePage(0, 0, 0, 0);
142:
143: $impref = new Imagick();
144: $impref->newImage(3, 10, new ImagickPixel('black'));
145: $psum = 0;
146: for ($c = 0; $c < 12; ++$c) {
147: $x = round(112 + ($c * $dcol));
148:
149: $imreg = $img->getImageRegion(3, 10, $x, 0);
150: $imreg->setImagePage(0, 0, 0, 0);
151:
152: $rmse = $imreg->compareImages($impref, Imagick::METRIC_ROOTMEANSQUAREDERROR);
153:
154: $psum += round(1.25 - $rmse[1]);
155: }
156: $imreg->clear();
157: $impref->clear();
158: if ($psum != 12) {
159: return false;
160: }
161:
162: $imref = new Imagick();
163: $imref->newImage($blkw, $blkw, new ImagickPixel('black'));
164:
165: $omrdata = array();
166:
167: for ($r = 0; $r < 30; ++$r) {
168: $omrdata[($r + $qstart)] = array();
169: $y = round($srow + ($r * $drow));
170:
171: for ($c = 0; $c < 12; ++$c) {
172:
173: $x = round($scol + ($c * $dcol));
174:
175: $imreg = $img->getImageRegion($blkw, $blkw, $x, $y);
176: $imreg->setImagePage(0, 0, 0, 0);
177:
178: $rmse = $imreg->compareImages($imref, Imagick::METRIC_ROOTMEANSQUAREDERROR);
179:
180: $opt_true = (2 * round(1.25 - $rmse[1]));
181:
182: $x += $dtf;
183:
184: $imreg = $img->getImageRegion($blkw, $blkw, $x, $y);
185: $imreg->setImagePage(0, 0, 0, 0);
186:
187: $rmse = $imreg->compareImages($imref, Imagick::METRIC_ROOTMEANSQUAREDERROR);
188:
189: $opt_false = round(1.25 - $rmse[1]);
190:
191: $val = ($opt_true + $opt_false - 1);
192: if ($val > 1) {
193: $val = 1;
194: }
195: $omrdata[($r + $qstart)][($c + 1)] = $val;
196: }
197: }
198: $imreg->clear();
199: $imref->clear();
200: return $omrdata;
201: }
202:
203: 204: 205: 206: 207: 208: 209: 210: 211:
212: function F_importOMRTestData($user_id, $date, $omr_testdata, $omr_answers, $overwrite = false)
213: {
214: require_once('../config/tce_config.php');
215: require_once('../../shared/code/tce_functions_test.php');
216: global $db, $l;
217:
218: if (count($omr_testdata) > (count($omr_answers) + 1)) {
219:
220: return false;
221: }
222: $test_id = intval($omr_testdata[0]);
223: $user_id = intval($user_id);
224: $time = strtotime($date);
225: $date = date(K_TIMESTAMP_FORMAT, $time);
226: $dateanswers = date(K_TIMESTAMP_FORMAT, ($time + 1));
227:
228: if (F_count_rows(K_TABLE_USERGROUP.', '.K_TABLE_TEST_GROUPS.' WHERE usrgrp_group_id=tstgrp_group_id AND tstgrp_test_id='.$test_id.' AND usrgrp_user_id='.$user_id.' LIMIT 1') == 0) {
229: return false;
230: }
231:
232: $testdata = F_getTestData($test_id);
233:
234: $sqls = 'SELECT test_id FROM '.K_TABLE_TESTS.' WHERE test_id='.$test_id.' AND test_repeatable=\'1\' LIMIT 1';
235: if ($rs = F_db_query($sqls, $db)) {
236: if ($ms = F_db_fetch_array($rs)) {
237:
238: $sqld = 'UPDATE '.K_TABLE_TEST_USER.' SET testuser_status=testuser_status+1 WHERE testuser_test_id='.$test_id.' AND testuser_user_id='.$user_id.' AND testuser_status>3';
239: if (!$rd = F_db_query($sqld, $db)) {
240: F_display_db_error();
241: }
242: } else {
243: if ($overwrite) {
244:
245: $sqld = 'DELETE FROM '.K_TABLE_TEST_USER.' WHERE testuser_test_id='.$test_id.' AND testuser_user_id='.$user_id.'';
246: if (!$rd = F_db_query($sqld, $db)) {
247: F_display_db_error();
248: }
249: } else {
250:
251: if (F_count_rows(K_TABLE_TEST_USER, 'WHERE testuser_test_id='.$test_id.' AND testuser_user_id='.$user_id.'') > 0) {
252: return false;
253: }
254: }
255: }
256: } else {
257: F_display_db_error();
258: }
259:
260:
261: $sql = 'INSERT INTO '.K_TABLE_TEST_USER.' (
262: testuser_test_id,
263: testuser_user_id,
264: testuser_status,
265: testuser_creation_time,
266: testuser_comment
267: ) VALUES (
268: '.$test_id.',
269: '.$user_id.',
270: 4,
271: \''.$date.'\',
272: \'OMR\'
273: )';
274: if (!$r = F_db_query($sql, $db)) {
275: F_display_db_error(false);
276: return false;
277: } else {
278:
279: $testuser_id = F_db_insert_id($db, K_TABLE_TEST_USER, 'testuser_id');
280: F_updateTestuserStat($date);
281: }
282:
283: $num_questions = count($omr_testdata) - 1;
284:
285: for ($q = 1; $q <= $num_questions; ++$q) {
286: $question_id = intval($omr_testdata[$q][0]);
287: $num_answers = count($omr_testdata[$q][1]);
288:
289: $sqlq = 'SELECT question_type, question_difficulty FROM '.K_TABLE_QUESTIONS.' WHERE question_id='.$question_id.' LIMIT 1';
290: if ($rq = F_db_query($sqlq, $db)) {
291: if ($mq = F_db_fetch_array($rq)) {
292:
293: $question_right_score = ($testdata['test_score_right'] * $mq['question_difficulty']);
294: $question_wrong_score = ($testdata['test_score_wrong'] * $mq['question_difficulty']);
295: $question_unanswered_score = ($testdata['test_score_unanswered'] * $mq['question_difficulty']);
296:
297: $sqll = 'INSERT INTO '.K_TABLE_TESTS_LOGS.' (
298: testlog_testuser_id,
299: testlog_question_id,
300: testlog_score,
301: testlog_creation_time,
302: testlog_display_time,
303: testlog_reaction_time,
304: testlog_order,
305: testlog_num_answers
306: ) VALUES (
307: '.$testuser_id.',
308: '.$question_id.',
309: '.$question_unanswered_score.',
310: \''.$date.'\',
311: \''.$date.'\',
312: 1,
313: '.$q.',
314: '.$num_answers.'
315: )';
316: if (!$rl = F_db_query($sqll, $db)) {
317: F_display_db_error(false);
318: return false;
319: }
320: $testlog_id = F_db_insert_id($db, K_TABLE_TESTS_LOGS, 'testlog_id');
321:
322: if ($mq['question_type'] == 1) {
323: $qscore = $question_unanswered_score;
324: } else {
325: $qscore = 0;
326: }
327: $unanswered = true;
328: $numselected = 0;
329:
330: for ($a = 1; $a <= $num_answers; ++$a) {
331: $answer_id = intval($omr_testdata[$q][1][$a]);
332: if (isset($omr_answers[$q][$a])) {
333: $answer_selected = $omr_answers[$q][$a];
334: } else {
335: $answer_selected = -1;
336: }
337:
338: $sqli = 'INSERT INTO '.K_TABLE_LOG_ANSWER.' (
339: logansw_testlog_id,
340: logansw_answer_id,
341: logansw_selected,
342: logansw_order
343: ) VALUES (
344: '.$testlog_id.',
345: '.$answer_id.',
346: '.$answer_selected.',
347: '.$a.'
348: )';
349: if (!$ri = F_db_query($sqli, $db)) {
350: F_display_db_error(false);
351: return false;
352: }
353:
354: if ($mq['question_type'] < 3) {
355:
356: $answer_isright = false;
357: $sqla = 'SELECT answer_isright FROM '.K_TABLE_ANSWERS.' WHERE answer_id='.$answer_id.' LIMIT 1';
358: if ($ra = F_db_query($sqla, $db)) {
359: if (($ma = F_db_fetch_array($ra))) {
360: $answer_isright = F_getBoolean($ma['answer_isright']);
361: switch ($mq['question_type']) {
362: case 1: {
363: if ($answer_selected == 1) {
364: ++$numselected;
365: if ($numselected == 1) {
366: $unanswered = false;
367: if ($answer_isright) {
368: $qscore = $question_right_score;
369: } else {
370: $qscore = $question_wrong_score;
371: }
372: } else {
373:
374: $unanswered = true;
375: $qscore = $question_unanswered_score;
376: }
377: }
378: break;
379: }
380: case 2: {
381: if ($answer_selected == -1) {
382: $qscore += $question_unanswered_score;
383: } elseif ($answer_selected == 0) {
384: $unanswered = false;
385: if ($answer_isright) {
386: $qscore += $question_wrong_score;
387: } else {
388: $qscore += $question_right_score;
389: }
390: } elseif ($answer_selected == 1) {
391: $unanswered = false;
392: if ($answer_isright) {
393: $qscore += $question_right_score;
394: } else {
395: $qscore += $question_wrong_score;
396: }
397: }
398: break;
399: }
400: }
401: }
402: } else {
403: F_display_db_error(false);
404: return false;
405: }
406: }
407: }
408: if ($mq['question_type'] == 2) {
409:
410: if (F_getBoolean($testdata['test_mcma_partial_score'])) {
411:
412: $qscore = round(($qscore / $num_answers), 3);
413: } else {
414:
415: if ($qscore >= ($question_right_score * $num_answers)) {
416:
417: $qscore = $question_right_score;
418: } elseif ($qscore == ($question_unanswered_score * $num_answers)) {
419:
420: $qscore = $question_unanswered_score;
421: } else {
422:
423: $qscore = $question_wrong_score;
424: }
425: }
426: }
427: if ($unanswered) {
428: $change_time = '';
429: } else {
430: $change_time = $dateanswers;
431: }
432:
433: $sqll = 'UPDATE '.K_TABLE_TESTS_LOGS.' SET
434: testlog_score='.$qscore.',
435: testlog_change_time='.F_empty_to_null($change_time).',
436: testlog_reaction_time=1000
437: WHERE testlog_id='.$testlog_id.'';
438: if (!$rl = F_db_query($sqll, $db)) {
439: F_display_db_error();
440: return false;
441: }
442: }
443: } else {
444: F_display_db_error(false);
445: return false;
446: }
447: }
448: return true;
449: }
450:
451:
452:
453:
454: