/**
 * Returns test data structure for selected user:
 * <ul>
 * <li>$data['all'] = total number of questions</li>
 * <li>$data['right'] = number of right answers for multiple-choice questions (score &gt; 50% max points)</li>
 * <li>$data['wrong'] = number of wrong answers for multiple-choice questions (score &lt;= 50% max points)</li>
 * <li>$data['textright'] = number of right answers for free-text questions (score &gt; 50% max points)</li>
 * <li>$data['textwrong'] = number of wrong answers for free-text questions (score &lt;= 50% max points)</li>
 * <li>$data['unanswered'] = total number of unanswered questions</li>
 * <li>$data['undisplayed'] = total number of undisplayed questions</li>
 * <li>$data['basic_score'] = basic points for each difficulty level of questions</li>
 * <li>$data['max_score'] = maximum test score</li>
 * <li>$data['score'] = user's score</li>
 * <li>$data['comment'] = user's test comment</li>
 * <li>$data['time'] = user's test start time</li>
 * </ul>
 * @param $test_id (int) test ID
 * @param $user_id (int) user's test ID
 * return array $data
 */
function F_getUserTestStat($test_id, $user_id)
{
    require_once '../config/tce_config.php';
    global $db, $l;
    $test_id = intval($test_id);
    $user_id = intval($user_id);
    $data = array();
    // get test default scores
    $sql = 'SELECT test_score_right, test_max_score, test_score_threshold
		FROM ' . K_TABLE_TESTS . '
		WHERE test_id=' . $test_id . '';
    if ($r = F_db_query($sql, $db)) {
        if ($m = F_db_fetch_array($r)) {
            $data['basic_score'] = $m['test_score_right'];
            $data['max_score'] = $m['test_max_score'];
            $data['score_threshold'] = $m['test_score_threshold'];
        }
    } else {
        F_display_db_error();
    }
    // total number of questions
    $data['all'] = F_count_rows(K_TABLE_TESTS_LOGS . ', ' . K_TABLE_TEST_USER . ', ' . K_TABLE_QUESTIONS, 'WHERE testlog_testuser_id=testuser_id AND testlog_question_id=question_id AND testuser_test_id=' . $test_id . ' AND testuser_user_id=' . $user_id . '');
    // number of right answers
    $data['right'] = F_count_rows(K_TABLE_TESTS_LOGS . ', ' . K_TABLE_TEST_USER . ', ' . K_TABLE_QUESTIONS, 'WHERE testlog_testuser_id=testuser_id AND testlog_question_id=question_id AND testuser_test_id=' . $test_id . ' AND testuser_user_id=' . $user_id . ' AND testlog_score>((question_difficulty*' . $data['basic_score'] . ')/2)');
    // number of wrong answers
    $data['wrong'] = F_count_rows(K_TABLE_TESTS_LOGS . ', ' . K_TABLE_TEST_USER . ', ' . K_TABLE_QUESTIONS, 'WHERE testlog_testuser_id=testuser_id AND testlog_question_id=question_id AND testuser_test_id=' . $test_id . ' AND testuser_user_id=' . $user_id . ' AND testlog_score<=((question_difficulty*' . $data['basic_score'] . ')/2)');
    // total number of unanswered questions
    $data['unanswered'] = F_count_rows(K_TABLE_TESTS_LOGS . ', ' . K_TABLE_TEST_USER, 'WHERE testlog_testuser_id=testuser_id AND testuser_test_id=' . $test_id . ' AND testuser_user_id=' . $user_id . ' AND testlog_change_time IS NULL');
    // total number of undisplayed questions
    $data['undisplayed'] = F_count_rows(K_TABLE_TESTS_LOGS . ', ' . K_TABLE_TEST_USER, 'WHERE testlog_testuser_id=testuser_id AND testuser_test_id=' . $test_id . ' AND testuser_user_id=' . $user_id . ' AND testlog_display_time IS NULL');
    // number of free-text unrated questions
    $data['unrated'] = F_count_rows(K_TABLE_TESTS_LOGS . ', ' . K_TABLE_TEST_USER, 'WHERE testlog_testuser_id=testuser_id AND  testuser_test_id=' . $test_id . ' AND testuser_user_id=' . $user_id . ' AND testlog_score IS NULL');
    // get user's score
    $sql = 'SELECT SUM(testlog_score) AS total_score
		FROM ' . K_TABLE_TESTS_LOGS . ', ' . K_TABLE_TEST_USER . '
		WHERE testlog_testuser_id=testuser_id
			AND testuser_user_id=' . $user_id . '
			AND testuser_test_id=' . $test_id . '
		GROUP BY testuser_id';
    if ($r = F_db_query($sql, $db)) {
        if ($m = F_db_fetch_array($r)) {
            $data['score'] = $m['total_score'];
        }
    } else {
        F_display_db_error();
    }
    // get user's test comment
    $data['comment'] = '';
    $sql = 'SELECT testuser_comment, testuser_creation_time
	FROM ' . K_TABLE_TEST_USER . '
	WHERE testuser_user_id=' . $user_id . '
		AND testuser_test_id=' . $test_id . '
	LIMIT 1';
    if ($r = F_db_query($sql, $db)) {
        if ($m = F_db_fetch_array($r)) {
            $data['comment'] = $m['testuser_comment'];
            $data['time'] = $m['testuser_creation_time'];
        }
    } else {
        F_display_db_error();
    }
    $sql = 'SELECT testuser_id, testuser_creation_time, testuser_status, MAX(testlog_change_time) AS test_end_time
		FROM ' . K_TABLE_TEST_USER . ', ' . K_TABLE_TESTS_LOGS . '
		WHERE testlog_testuser_id=testuser_id
			AND testuser_test_id=' . $test_id . '
			AND testuser_user_id=' . $user_id . '
			AND testuser_status>0
		GROUP BY testuser_id, testuser_creation_time, testuser_status
		LIMIT 1';
    if ($r = F_db_query($sql, $db)) {
        if ($m = F_db_fetch_array($r)) {
            $data['test_start_time'] = $m['testuser_creation_time'];
            $data['test_end_time'] = $m['test_end_time'];
            $data['testuser_id'] = $m['testuser_id'];
            $data['testuser_status'] = $m['testuser_status'];
        }
    } else {
        F_display_db_error();
    }
    return $data;
}
/**
 * Display user selection XHTML table (popup mode).
 * @author Nicola Asuni
 * @since 2012-04-14
 * @param $order_field (string) Order by column name.
 * @param $orderdir (int) Order direction.
 * @param $firstrow (int) Number of first row to display.
 * @param $rowsperpage (int) Number of rows per page.
 * @param $group_id (int) ID of the group (default = 0 = no specific group selected).
 * @param $andwhere (string) Additional SQL WHERE query conditions.
 * @param $searchterms (string) Search terms.
 * @param string $cid ID of the calling form field.
 * @return false in case of empty database, true otherwise
 */
function F_show_select_user_popup($order_field, $orderdir, $firstrow, $rowsperpage, $group_id = 0, $andwhere = '', $searchterms = '', $cid = 0)
{
    global $l, $db;
    require_once '../config/tce_config.php';
    require_once '../../shared/code/tce_functions_page.php';
    require_once '../../shared/code/tce_functions_form.php';
    $filter = 'cid=' . $cid;
    if ($l['a_meta_dir'] == 'rtl') {
        $txtalign = 'right';
        $numalign = 'left';
    } else {
        $txtalign = 'left';
        $numalign = 'right';
    }
    $order_field = F_escape_sql($db, $order_field);
    $orderdir = intval($orderdir);
    $firstrow = intval($firstrow);
    $rowsperpage = intval($rowsperpage);
    $group_id = intval($group_id);
    if (empty($order_field) or !in_array($order_field, array('user_id', 'user_name', 'user_password', 'user_email', 'user_regdate', 'user_ip', 'user_firstname', 'user_lastname', 'user_birthdate', 'user_birthplace', 'user_regnumber', 'user_ssn', 'user_level', 'user_verifycode'))) {
        $order_field = 'user_lastname,user_firstname';
    }
    if ($orderdir == 0) {
        $nextorderdir = 1;
        $full_order_field = $order_field;
    } else {
        $nextorderdir = 0;
        $full_order_field = $order_field . ' DESC';
    }
    if (!F_count_rows(K_TABLE_USERS)) {
        // if the table is void (no items) display message
        F_print_error('MESSAGE', $l['m_databasempty']);
        return FALSE;
    }
    $wherequery = '';
    if ($group_id > 0) {
        $wherequery = ', ' . K_TABLE_USERGROUP . ' WHERE user_id=usrgrp_user_id	AND usrgrp_group_id=' . $group_id . '';
        $filter .= '&amp;group_id=' . $group_id . '';
    }
    if (empty($wherequery)) {
        $wherequery = ' WHERE';
    } else {
        $wherequery .= ' AND';
    }
    $wherequery .= ' (user_id>1)';
    if ($_SESSION['session_user_level'] < K_AUTH_ADMINISTRATOR) {
        // filter for level
        $wherequery .= ' AND ((user_level<' . $_SESSION['session_user_level'] . ') OR (user_id=' . $_SESSION['session_user_id'] . '))';
        // filter for groups
        $wherequery .= ' AND user_id IN (SELECT tb.usrgrp_user_id
			FROM ' . K_TABLE_USERGROUP . ' AS ta, ' . K_TABLE_USERGROUP . ' AS tb
			WHERE ta.usrgrp_group_id=tb.usrgrp_group_id
				AND ta.usrgrp_user_id=' . intval($_SESSION['session_user_id']) . '
				AND tb.usrgrp_user_id=user_id)';
    }
    if (!empty($andwhere)) {
        $wherequery .= ' AND (' . $andwhere . ')';
    }
    $sql = 'SELECT * FROM ' . K_TABLE_USERS . $wherequery . ' ORDER BY ' . $full_order_field;
    if (K_DATABASE_TYPE == 'ORACLE') {
        $sql = 'SELECT * FROM (' . $sql . ') WHERE rownum BETWEEN ' . $firstrow . ' AND ' . ($firstrow + $rowsperpage) . '';
    } else {
        $sql .= ' LIMIT ' . $rowsperpage . ' OFFSET ' . $firstrow . '';
    }
    if ($r = F_db_query($sql, $db)) {
        if ($m = F_db_fetch_array($r)) {
            // -- Table structure with links:
            echo '<div class="container">';
            echo '<table class="userselect" style="font-size:80%;">' . K_NEWLINE;
            // table header
            echo '<tr>' . K_NEWLINE;
            if (strlen($searchterms) > 0) {
                $filter .= '&amp;searchterms=' . urlencode($searchterms);
            }
            echo F_select_table_header_element('user_name', $nextorderdir, $l['h_login_name'], $l['w_user'], $order_field, $filter);
            echo F_select_table_header_element('user_lastname', $nextorderdir, $l['h_lastname'], $l['w_lastname'], $order_field, $filter);
            echo F_select_table_header_element('user_firstname', $nextorderdir, $l['h_firstname'], $l['w_firstname'], $order_field, $filter);
            echo F_select_table_header_element('user_email', $nextorderdir, $l['h_email'], $l['w_email'], $order_field, $filter);
            echo F_select_table_header_element('user_regnumber', $nextorderdir, $l['h_regcode'], $l['w_regcode'], $order_field, $filter);
            echo F_select_table_header_element('user_level', $nextorderdir, $l['h_level'], $l['w_level'], $order_field, $filter);
            echo F_select_table_header_element('user_regdate', $nextorderdir, $l['h_regdate'], $l['w_regdate'], $order_field, $filter);
            //echo '<th title="'.$l['h_group_name'].'">'.$l['w_groups'].'</th>'.K_NEWLINE;
            echo '</tr>' . K_NEWLINE;
            $itemcount = 0;
            do {
                $itemcount++;
                // on click the user ID will be returned on the calling form field
                $jsaction = 'javascript:window.opener.document.getElementById(\'' . $cid . '\').value=' . $m['user_id'] . ';';
                $jsaction .= 'window.opener.document.getElementById(\'' . $cid . '\').onchange();';
                $jsaction .= 'window.close();';
                echo '<tr>' . K_NEWLINE;
                echo '<td style="text-align:' . $txtalign . ';">&nbsp;<a href="#" onclick="' . $jsaction . '" title="[' . $l['w_select'] . ']">' . htmlspecialchars($m['user_name'], ENT_NOQUOTES, $l['a_meta_charset']) . '</a></td>' . K_NEWLINE;
                echo '<td style="text-align:' . $txtalign . ';">&nbsp;' . htmlspecialchars($m['user_lastname'], ENT_NOQUOTES, $l['a_meta_charset']) . '</td>' . K_NEWLINE;
                echo '<td style="text-align:' . $txtalign . ';">&nbsp;' . htmlspecialchars($m['user_firstname'], ENT_NOQUOTES, $l['a_meta_charset']) . '</td>' . K_NEWLINE;
                echo '<td style="text-align:' . $txtalign . ';">&nbsp;' . htmlspecialchars($m['user_email'], ENT_NOQUOTES, $l['a_meta_charset']) . '</td>' . K_NEWLINE;
                echo '<td style="text-align:' . $txtalign . ';">&nbsp;' . htmlspecialchars($m['user_regnumber'], ENT_NOQUOTES, $l['a_meta_charset']) . '</td>' . K_NEWLINE;
                echo '<td>&nbsp;' . $m['user_level'] . '</td>' . K_NEWLINE;
                echo '<td>&nbsp;' . htmlspecialchars($m['user_regdate'], ENT_NOQUOTES, $l['a_meta_charset']) . '</td>' . K_NEWLINE;
                /*
                // comma separated list of user's groups
                $grp = '';
                $sqlg = 'SELECT *
                	FROM '.K_TABLE_GROUPS.', '.K_TABLE_USERGROUP.'
                	WHERE usrgrp_group_id=group_id
                		AND usrgrp_user_id='.$m['user_id'].'
                	ORDER BY group_name';
                if ($rg = F_db_query($sqlg, $db)) {
                	while ($mg = F_db_fetch_array($rg)) {
                		$grp .= $mg['group_name'].', ';
                	}
                } else {
                	F_display_db_error();
                }
                echo '<td style="text-align:'.$txtalign.';">&nbsp;'.htmlspecialchars(substr($grp,0,-2), ENT_NOQUOTES, $l['a_meta_charset']).'</td>'.K_NEWLINE;
                */
                echo '</tr>' . K_NEWLINE;
            } while ($m = F_db_fetch_array($r));
            echo '</table>' . K_NEWLINE;
            echo '<input type="hidden" name="order_field" id="order_field" value="' . $order_field . '" />' . K_NEWLINE;
            echo '<input type="hidden" name="orderdir" id="orderdir" value="' . $orderdir . '" />' . K_NEWLINE;
            echo '<input type="hidden" name="firstrow" id="firstrow" value="' . $firstrow . '" />' . K_NEWLINE;
            echo '<input type="hidden" name="rowsperpage" id="rowsperpage" value="' . $rowsperpage . '" />' . K_NEWLINE;
            echo '<div class="row"><hr /></div>' . K_NEWLINE;
            // ---------------------------------------------------------------
            // -- page jumper (menu for successive pages)
            if ($rowsperpage > 0) {
                $sql = 'SELECT count(*) AS total FROM ' . K_TABLE_USERS . '' . $wherequery . '';
                if (!empty($order_field)) {
                    $param_array = '&amp;order_field=' . urlencode($order_field) . '';
                }
                if (!empty($orderdir)) {
                    $param_array .= '&amp;orderdir=' . $orderdir . '';
                }
                if (!empty($group_id)) {
                    $param_array .= '&amp;group_id=' . $group_id . '';
                }
                if (!empty($searchterms)) {
                    $param_array .= '&amp;searchterms=' . urlencode($searchterms) . '';
                }
                $param_array .= '&amp;submitted=1';
                F_show_page_navigator($_SERVER['SCRIPT_NAME'], $sql, $firstrow, $rowsperpage, $param_array);
            }
            //echo '<div class="pagehelp">'.$l['hp_select_users'].'</div>'.K_NEWLINE;
            echo '</div>' . K_NEWLINE;
        } else {
            F_print_error('MESSAGE', $l['m_search_void']);
        }
    } else {
        F_display_db_error();
    }
    return TRUE;
}
/**
 * Check if specified fields are unique on table.
 * @param $table (string) table name
 * @param $where (string) SQL where clause
 * @param $fieldname (mixed) name of table column to check
 * @param $fieldid (mixed) ID of table row to check
 * @return bool true if unique, false otherwise
 */
function F_check_unique($table, $where, $fieldname = FALSE, $fieldid = FALSE)
{
    require_once '../config/tce_config.php';
    global $l, $db;
    $sqlc = 'SELECT * FROM ' . $table . ' WHERE ' . $where . ' LIMIT 1';
    if ($rc = F_db_query($sqlc, $db)) {
        if ($fieldname === FALSE and $fieldid === FALSE and F_count_rows($table, 'WHERE ' . $where) > 0) {
            return FALSE;
        }
        if ($mc = F_db_fetch_array($rc)) {
            if ($mc[$fieldname] == $fieldid) {
                return TRUE;
                // the values are unchanged
            }
        } else {
            // the new values are not yet present on table
            return TRUE;
        }
    } else {
        F_display_db_error();
    }
    // another table row contains the same values
    return FALSE;
}
echo '</div>' . K_NEWLINE;
// question difficulty
$items = array();
for ($i = 0; $i <= K_QUESTION_DIFFICULTY_LEVELS; ++$i) {
    $items[$i] = $i;
}
echo getFormRowSelectBox('question_difficulty', $l['w_question_difficulty'], $l['h_question_difficulty'], '', $question_difficulty, $items, '');
// question position
echo '<div class="row">' . K_NEWLINE;
echo '<span class="label">' . K_NEWLINE;
echo '<label for="question_position">' . $l['w_position'] . '</label>' . K_NEWLINE;
echo '</span>' . K_NEWLINE;
echo '<span class="formw">' . K_NEWLINE;
echo '<select name="question_position" id="question_position" size="0" title="' . $l['h_position'] . '">' . K_NEWLINE;
if (isset($question_id) and $question_id > 0) {
    $max_position = 1 + F_count_rows(K_TABLE_QUESTIONS, "WHERE question_subject_id=" . $question_subject_id . " AND question_position>0 AND question_id<>" . $question_id . "");
} else {
    $max_position = 0;
}
echo '<option value="0">&nbsp;</option>' . K_NEWLINE;
for ($pos = 1; $pos <= $max_position; $pos++) {
    echo '<option value="' . $pos . '"';
    if ($pos == $question_position) {
        echo ' selected="selected"';
    }
    echo '>' . $pos . '</option>' . K_NEWLINE;
}
echo '<option value="' . ($max_position + 1) . '" style="color:#ff0000">' . ($max_position + 1) . '</option>' . K_NEWLINE;
echo '</select>' . K_NEWLINE;
echo '<input type="hidden" name="max_position" id="max_position" value="' . $max_position . '" />' . K_NEWLINE;
echo '</span>' . K_NEWLINE;
Example #5
0
        } else {
            $login_error = true;
        }
    }
    // end of brute-force check
}
if (!isset($pagelevel)) {
    // set default page level
    $pagelevel = 0;
}
// check client SSL certificate if required
if (K_AUTH_SSL_LEVEL !== false and K_AUTH_SSL_LEVEL <= $pagelevel) {
    $sslids = preg_replace('/[^0-9,]*/', '', K_AUTH_SSLIDS);
    if (!empty($sslids)) {
        $client_hash = F_getSSLClientHash();
        $valid_ssl = F_count_rows(K_TABLE_SSLCERTS, 'WHERE ssl_hash=\'' . $client_hash . '\' AND ssl_id IN (' . $sslids . ')');
        if ($valid_ssl == 0) {
            $thispage_title = $l['t_login_form'];
            //set page title
            require_once '../code/tce_page_header.php';
            F_print_error('ERROR', $l['m_ssl_certificate_required']);
            require_once '../code/tce_page_footer.php';
            exit;
            //break page here
        }
    }
}
// check user's level
if ($pagelevel) {
    // pagelevel=0 means access to anonymous user
    // pagelevel >= 1
Example #6
0
/**
 * Display a list of selected questions.
 * @author Nicola Asuni
 * @since 2005-07-06
 * @param $wherequery (string) question selection query
 * @param $subject_module_id (string) module ID
 * @param $subject_id (string) topic ID
 * @param $order_field (string) order by column name
 * @param $orderdir (int) oreder direction
 * @param $firstrow (int) number of first row to display
 * @param $rowsperpage (int) number of rows per page
 * @param $hide_answers (boolean) if true hide answers
 * @return false in case of empty database, true otherwise
 */
function F_show_select_questions($wherequery, $subject_module_id, $subject_id, $order_field, $orderdir, $firstrow, $rowsperpage, $hide_answers = false)
{
    global $l, $db;
    require_once '../config/tce_config.php';
    require_once '../../shared/code/tce_functions_page.php';
    $subject_module_id = intval($subject_module_id);
    $subject_id = intval($subject_id);
    $orderdir = intval($orderdir);
    $firstrow = intval($firstrow);
    $rowsperpage = intval($rowsperpage);
    if (empty($order_field) or !in_array($order_field, array('question_id', 'question_subject_id', 'question_description', 'question_explanation', 'question_type', 'question_difficulty', 'question_enabled', 'question_position', 'question_timer', 'question_fullscreen', 'question_inline_answers', 'question_auto_next', 'question_enabled DESC, question_position, CAST(question_description as varchar2(100))', 'question_enabled DESC, question_position, question_description'))) {
        $order_field = 'question_description';
    }
    if ($orderdir == 0) {
        $nextorderdir = 1;
        $full_order_field = $order_field;
    } else {
        $nextorderdir = 0;
        $full_order_field = $order_field . ' DESC';
    }
    if (!F_count_rows(K_TABLE_QUESTIONS)) {
        //if the table is void (no items) display message
        F_print_error('MESSAGE', $l['m_databasempty']);
        return FALSE;
    }
    if (empty($wherequery)) {
        $wherequery = 'WHERE question_subject_id=' . $subject_id . '';
    } else {
        $wherequery = F_escape_sql($db, $wherequery);
        $wherequery .= ' AND question_subject_id=' . $subject_id . '';
    }
    $sql = 'SELECT *
		FROM ' . K_TABLE_QUESTIONS . '
		' . $wherequery . '
		ORDER BY ' . $full_order_field;
    if (K_DATABASE_TYPE == 'ORACLE') {
        $sql = 'SELECT * FROM (' . $sql . ') WHERE rownum BETWEEN ' . $firstrow . ' AND ' . ($firstrow + $rowsperpage) . '';
    } else {
        $sql .= ' LIMIT ' . $rowsperpage . ' OFFSET ' . $firstrow . '';
    }
    if ($r = F_db_query($sql, $db)) {
        $questlist = '';
        $itemcount = $firstrow;
        while ($m = F_db_fetch_array($r)) {
            $itemcount++;
            $questlist .= '<li>' . K_NEWLINE;
            $questlist .= '<strong>' . $itemcount . '.</strong> ';
            $questlist .= '<input type="checkbox" name="questionid' . $itemcount . '" id="questionid' . $itemcount . '" value="' . $m['question_id'] . '" title="' . $l['w_select'] . '"';
            if (isset($_REQUEST['checkall']) and $_REQUEST['checkall'] == 1) {
                $questlist .= ' checked="checked"';
            }
            $questlist .= ' />';
            // display question description
            if (F_getBoolean($m['question_enabled'])) {
                $questlist .= '<acronym class="onbox" title="' . $l['w_enabled'] . '">+</acronym>';
            } else {
                $questlist .= '<acronym class="offbox" title="' . $l['w_disabled'] . '">-</acronym>';
            }
            switch ($m['question_type']) {
                case 1:
                    $questlist .= ' <acronym class="offbox" title="' . $l['w_single_answer'] . '">S</acronym>';
                    break;
                case 2:
                    $questlist .= ' <acronym class="offbox" title="' . $l['w_multiple_answers'] . '">M</acronym>';
                    break;
                case 3:
                    $questlist .= ' <acronym class="offbox" title="' . $l['w_free_answer'] . '">T</acronym>';
                    break;
                case 4:
                    $questlist .= ' <acronym class="offbox" title="' . $l['w_ordering_answer'] . '">O</acronym>';
                    break;
            }
            $questlist .= ' <acronym class="offbox" title="' . $l['h_question_difficulty'] . '">' . $m['question_difficulty'] . '</acronym>';
            if ($m['question_position'] > 0) {
                $questlist .= ' <acronym class="onbox" title="' . $l['h_position'] . '">' . intval($m['question_position']) . '</acronym>';
            } else {
                $questlist .= ' <acronym class="offbox" title="' . $l['h_position'] . '">&nbsp;</acronym>';
            }
            if (F_getBoolean($m['question_fullscreen'])) {
                $questlist .= ' <acronym class="onbox" title="' . $l['w_fullscreen'] . ': ' . $l['w_enabled'] . '">F</acronym>';
            } else {
                $questlist .= ' <acronym class="offbox" title="' . $l['w_fullscreen'] . ': ' . $l['w_disabled'] . '">&nbsp;</acronym>';
            }
            if (F_getBoolean($m['question_inline_answers'])) {
                $questlist .= ' <acronym class="onbox" title="' . $l['w_inline_answers'] . ': ' . $l['w_enabled'] . '">I</acronym>';
            } else {
                $questlist .= ' <acronym class="offbox" title="' . $l['w_inline_answers'] . ': ' . $l['w_disabled'] . '">&nbsp;</acronym>';
            }
            if (F_getBoolean($m['question_auto_next'])) {
                $questlist .= ' <acronym class="onbox" title="' . $l['w_auto_next'] . ': ' . $l['w_enabled'] . '">A</acronym>';
            } else {
                $questlist .= ' <acronym class="offbox" title="' . $l['w_auto_next'] . ': ' . $l['w_disabled'] . '">&nbsp;</acronym>';
            }
            if ($m['question_timer'] > 0) {
                $questlist .= ' <acronym class="onbox" title="' . $l['h_question_timer'] . '">' . intval($m['question_timer']) . '</acronym>';
            } else {
                $questlist .= ' <acronym class="offbox" title="' . $l['h_question_timer'] . '">&nbsp;</acronym>';
            }
            $questlist .= ' <a href="tce_edit_question.php?subject_module_id=' . $subject_module_id . '&amp;question_subject_id=' . $subject_id . '&amp;question_id=' . $m['question_id'] . '" title="' . $l['t_questions_editor'] . ' [ID = ' . $m['question_id'] . ']" class="xmlbutton">' . $l['w_edit'] . '</a>';
            $questlist .= '<br /><br />' . K_NEWLINE;
            $questlist .= '<div class="paddingleft">' . F_decode_tcecode($m['question_description']) . '</div>' . K_NEWLINE;
            if (K_ENABLE_QUESTION_EXPLANATION and !empty($m['question_explanation'])) {
                $questlist .= '<div class="paddingleft"><br /><span class="explanation">' . $l['w_explanation'] . ':</span><br />' . F_decode_tcecode($m['question_explanation']) . '</div>' . K_NEWLINE;
            }
            if (!$hide_answers) {
                // display alternative answers
                $sqla = 'SELECT *
					FROM ' . K_TABLE_ANSWERS . '
					WHERE answer_question_id=\'' . $m['question_id'] . '\'
					ORDER BY answer_enabled DESC,answer_position,answer_isright DESC';
                if ($ra = F_db_query($sqla, $db)) {
                    $answlist = '';
                    while ($ma = F_db_fetch_array($ra)) {
                        $answlist .= '<li>';
                        if (F_getBoolean($ma['answer_enabled'])) {
                            $answlist .= '<acronym class="onbox" title="' . $l['w_enabled'] . '">+</acronym>';
                        } else {
                            $answlist .= '<acronym class="offbox" title="' . $l['w_disabled'] . '">-</acronym>';
                        }
                        if ($m['question_type'] != 4) {
                            if (F_getBoolean($ma['answer_isright'])) {
                                $answlist .= ' <acronym class="okbox" title="' . $l['h_answer_right'] . '">T</acronym>';
                            } else {
                                $answlist .= ' <acronym class="nobox" title="' . $l['h_answer_wrong'] . '">F</acronym>';
                            }
                        }
                        if ($ma['answer_position'] > 0) {
                            $answlist .= ' <acronym class="onbox" title="' . $l['h_position'] . '">' . intval($ma['answer_position']) . '</acronym>';
                        } else {
                            $answlist .= ' <acronym class="offbox" title="' . $l['h_position'] . '">&nbsp;</acronym>';
                        }
                        if ($ma['answer_keyboard_key'] > 0) {
                            $answlist .= ' <acronym class="onbox" title="' . $l['h_answer_keyboard_key'] . '">' . F_text_to_xml(chr($ma['answer_keyboard_key'])) . '</acronym>';
                        } else {
                            $answlist .= ' <acronym class="offbox" title="' . $l['h_answer_keyboard_key'] . '">&nbsp;</acronym>';
                        }
                        $answlist .= ' <a href="tce_edit_answer.php?subject_module_id=' . $subject_module_id . '&amp;question_subject_id=' . $subject_id . '&amp;answer_question_id=' . $m['question_id'] . '&amp;answer_id=' . $ma['answer_id'] . '" title="' . $l['t_answers_editor'] . ' [ID = ' . $ma['answer_id'] . ']" class="xmlbutton">' . $l['w_edit'] . '</a>';
                        //$answlist .= " ";
                        //$answlist .= "".F_decode_tcecode($ma['answer_description'])."";
                        $answlist .= '<br /><br />' . K_NEWLINE;
                        $answlist .= '<div class="paddingleft">' . F_decode_tcecode($ma['answer_description']) . '</div>' . K_NEWLINE;
                        if (K_ENABLE_ANSWER_EXPLANATION and !empty($ma['answer_explanation'])) {
                            $answlist .= '<div class="paddingleft"><br /><span class="explanation">' . $l['w_explanation'] . ':</span><br />' . F_decode_tcecode($ma['answer_explanation']) . '</div>' . K_NEWLINE;
                        }
                        $answlist .= '</li>' . K_NEWLINE;
                    }
                    if (strlen($answlist) > 0) {
                        $questlist .= "<ol class=\"answer\">\n" . $answlist . "</ol><br /><br />\n";
                    }
                } else {
                    F_display_db_error();
                }
            }
            // end if hide_answers
            $questlist .= '</li>' . K_NEWLINE;
        }
        if (strlen($questlist) > 0) {
            // display the list
            echo '<ul class="question">' . K_NEWLINE;
            echo $questlist;
            echo '</ul>' . K_NEWLINE;
            echo '<div class="row"><hr /></div>' . K_NEWLINE;
            // check/uncheck all options
            echo '<span dir="' . $l['a_meta_dir'] . '">';
            echo '<input type="radio" name="checkall" id="checkall1" value="1" onclick="document.getElementById(\'form_selectquestions\').submit()" />';
            echo '<label for="checkall1">' . $l['w_check_all'] . '</label> ';
            echo '<input type="radio" name="checkall" id="checkall0" value="0" onclick="document.getElementById(\'form_selectquestions\').submit()" />';
            echo '<label for="checkall0">' . $l['w_uncheck_all'] . '</label>';
            echo '</span>' . K_NEWLINE;
            echo '&nbsp;';
            if ($l['a_meta_dir'] == 'rtl') {
                $arr = '&larr;';
            } else {
                $arr = '&rarr;';
            }
            // action options
            echo '<select name="menu_action" id="menu_action" size="0">' . K_NEWLINE;
            echo '<option value="0" style="color:gray">' . $l['m_with_selected'] . '</option>' . K_NEWLINE;
            echo '<option value="enable">' . $l['w_enable'] . '</option>' . K_NEWLINE;
            echo '<option value="disable">' . $l['w_disable'] . '</option>' . K_NEWLINE;
            echo '<option value="delete">' . $l['w_delete'] . '</option>' . K_NEWLINE;
            echo '<option value="copy">' . $l['w_copy'] . ' ' . $arr . '</option>' . K_NEWLINE;
            echo '<option value="move">' . $l['w_move'] . ' ' . $arr . '</option>' . K_NEWLINE;
            echo '</select>' . K_NEWLINE;
            // select new topic (for copy or move action)
            echo '<select name="new_subject_id" id="new_subject_id" size="0" title="' . $l['h_subject'] . '">' . K_NEWLINE;
            $sql = F_select_module_subjects_sql('module_enabled=\'1\' AND subject_enabled=\'1\'');
            if ($r = F_db_query($sql, $db)) {
                echo '<option value="0" style="color:gray">' . $l['w_subject'] . '</option>' . K_NEWLINE;
                $prev_module_id = 0;
                while ($m = F_db_fetch_array($r)) {
                    if ($m['module_id'] != $prev_module_id) {
                        $prev_module_id = $m['module_id'];
                        echo '<option value="0" style="color:gray;font-weight:bold;" disabled="disabled">* ' . htmlspecialchars($m['module_name'], ENT_NOQUOTES, $l['a_meta_charset']) . '</option>' . K_NEWLINE;
                    }
                    echo '<option value="' . $m['subject_id'] . '">&nbsp;&nbsp;&nbsp;&nbsp;' . htmlspecialchars($m['subject_name'], ENT_NOQUOTES, $l['a_meta_charset']) . '</option>' . K_NEWLINE;
                }
            } else {
                echo '</select>' . K_NEWLINE;
                F_display_db_error();
            }
            echo '</select>' . K_NEWLINE;
            // submit button
            F_submit_button("update", $l['w_update'], $l['h_update']);
        }
        // ---------------------------------------------------------------
        // -- page jumper (menu for successive pages)
        if ($rowsperpage > 0) {
            $sql = 'SELECT count(*) AS total FROM ' . K_TABLE_QUESTIONS . ' ' . $wherequery . '';
            if (!empty($order_field)) {
                $param_array = '&amp;order_field=' . urlencode($order_field) . '';
            }
            if (!empty($orderdir)) {
                $param_array .= '&amp;orderdir=' . $orderdir . '';
            }
            if (!empty($hide_answers)) {
                $param_array .= '&amp;hide_answers=' . intval($hide_answers) . '';
            }
            $param_array .= '&amp;subject_module_id=' . $subject_module_id . '';
            $param_array .= '&amp;subject_id=' . $subject_id . '';
            $param_array .= '&amp;submitted=1';
            F_show_page_navigator($_SERVER['SCRIPT_NAME'], $sql, $firstrow, $rowsperpage, $param_array);
        }
    } else {
        F_display_db_error();
    }
    return TRUE;
}
/**
 * Returns the number of omitted questions (unanswered + undisplayed).
 * @param $test_id (int) test ID
 * @return integer number
 */
function F_getNumOmittedQuestions($test_id)
{
    require_once '../config/tce_config.php';
    global $db, $l;
    $test_id = intval($test_id);
    $user_id = intval($_SESSION['session_user_id']);
    // get th number of omitted questions
    $omitted = F_count_rows(K_TABLE_TEST_USER . ', ' . K_TABLE_TESTS_LOGS, 'WHERE testlog_testuser_id=testuser_id
			AND testuser_test_id=' . $test_id . '
			AND testuser_user_id=' . $user_id . '
			AND (testlog_change_time IS NULL OR testlog_display_time IS NULL)');
    return $omitted;
}
                        $pdf->writeHTMLCell(0, $data_cell_height, PDF_MARGIN_LEFT + 2 * $data_cell_width_third, $pdf->GetY(), F_decode_tcecode($question_description), 1, 1);
                        //$pdf->Ln(2);
                        $itemcount++;
                        // answers statistics
                        $sqla = 'SELECT *
							FROM ' . K_TABLE_ANSWERS . '
							WHERE answer_question_id=' . $mr['question_id'] . '
							ORDER BY answer_id';
                        if ($ra = F_db_query($sqla, $db)) {
                            $answcount = 1;
                            while ($ma = F_db_fetch_array($ra)) {
                                $num_all_answers = F_count_rows(K_TABLE_TEST_USER . ', ' . K_TABLE_TESTS_LOGS . ', ' . K_TABLE_ANSWERS . ', ' . K_TABLE_LOG_ANSWER . ' WHERE logansw_answer_id=answer_id AND logansw_testlog_id=testlog_id AND testlog_testuser_id=testuser_id AND testuser_test_id=' . $test_id . ' AND testlog_question_id=' . $mr['question_id'] . '');
                                $num_answers = F_count_rows(K_TABLE_TEST_USER . ', ' . K_TABLE_TESTS_LOGS . ', ' . K_TABLE_ANSWERS . ', ' . K_TABLE_LOG_ANSWER . ' WHERE answer_id=' . $ma['answer_id'] . ' AND logansw_answer_id=answer_id AND logansw_testlog_id=testlog_id AND testlog_testuser_id=testuser_id AND testuser_test_id=' . $test_id . ' AND testlog_question_id=' . $mr['question_id'] . '');
                                $right_answers = F_count_rows(K_TABLE_TEST_USER . ', ' . K_TABLE_TESTS_LOGS . ', ' . K_TABLE_ANSWERS . ', ' . K_TABLE_LOG_ANSWER . ' WHERE answer_id=' . $ma['answer_id'] . ' AND logansw_answer_id=answer_id AND logansw_testlog_id=testlog_id AND testlog_testuser_id=testuser_id AND testuser_test_id=' . $test_id . ' AND testlog_question_id=' . $mr['question_id'] . ' AND ((answer_isright=\'0\' AND logansw_selected=0) OR (answer_isright=\'1\' AND logansw_selected=1) OR (answer_position IS NOT NULL AND logansw_position IS NOT NULL AND answer_position=logansw_position))');
                                $wrong_answers = F_count_rows(K_TABLE_TEST_USER . ', ' . K_TABLE_TESTS_LOGS . ', ' . K_TABLE_ANSWERS . ', ' . K_TABLE_LOG_ANSWER . ' WHERE answer_id=' . $ma['answer_id'] . ' AND logansw_answer_id=answer_id AND logansw_testlog_id=testlog_id AND testlog_testuser_id=testuser_id AND testuser_test_id=' . $test_id . ' AND testlog_question_id=' . $mr['question_id'] . ' AND ((answer_isright=\'0\' AND logansw_selected=1) OR (answer_isright=\'1\' AND logansw_selected=0) OR (answer_position IS NOT NULL AND answer_position!=logansw_position))');
                                $unanswered = F_count_rows(K_TABLE_TEST_USER . ', ' . K_TABLE_TESTS_LOGS . ', ' . K_TABLE_ANSWERS . ', ' . K_TABLE_LOG_ANSWER . ' WHERE answer_id=' . $ma['answer_id'] . ' AND logansw_answer_id=answer_id AND logansw_testlog_id=testlog_id AND testlog_testuser_id=testuser_id AND testuser_test_id=' . $test_id . ' AND testlog_question_id=' . $mr['question_id'] . ' AND logansw_selected=-1');
                                $pdf->SetFont($numberfont, '', 6);
                                $pdf->Cell(2 * $data_cell_width_third, $data_cell_height, '', '', 0, 'R', 0);
                                $pdf->Cell($data_cell_width_third, $data_cell_height, $answcount, 1, 0, 'R', 0);
                                $perc = 0;
                                if ($num_all_answers > 0) {
                                    $perc = $num_answers / $num_all_answers;
                                }
                                $pdf->Cell($data_cell_width - $data_cell_width_third, $data_cell_height, $num_answers . ' ' . F_formatPdfPercentage($perc), 1, 0, 'R', 0);
                                $pdf->Cell(2 * $data_cell_width + $data_cell_width_third, $data_cell_height, '', 1, 0, 'C', 0);
                                $perc = 0;
                                if ($num_answers > 0) {
                                    $perc = $right_answers / $num_answers;
                                }
                                $pdf->Cell($data_cell_width, $data_cell_height, $right_answers . ' ' . F_formatPdfPercentage($perc), 1, 0, 'R', 0);
                                $perc = 0;
/**
 * Import user's test data from OMR.
 * @param $user_id (int) user ID.
 * @param $date (string) date-time field.
 * @param $omr_testdata (array) Array containing test data.
 * @param $omr_answers (array) Array containing test answers (from OMR).
 * @return boolean TRUE in case of success, FALSE otherwise.
 */
function F_importOMRTestData($user_id, $date, $omr_testdata, $omr_answers)
{
    require_once '../config/tce_config.php';
    require_once '../../shared/code/tce_functions_test.php';
    global $db, $l;
    // check arrays
    if (count($omr_testdata) > count($omr_answers) + 1) {
        // arrays must contain the same amount of questions
        return false;
    }
    $test_id = intval($omr_testdata[0]);
    $user_id = intval($user_id);
    $time = strtotime($date);
    $date = date(K_TIMESTAMP_FORMAT, $time);
    $dateanswers = date(K_TIMESTAMP_FORMAT, $time + 1);
    // check user's group
    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) {
        return false;
    }
    // get test data
    $testdata = F_getTestData($test_id);
    // 1. delete previous test data
    $sqld = 'DELETE FROM ' . K_TABLE_TEST_USER . ' WHERE testuser_test_id=' . $test_id . ' AND testuser_user_id=' . $user_id . '';
    if (!($rd = F_db_query($sqld, $db))) {
        F_display_db_error();
    }
    // 2. create new user's test entry
    // ------------------------------
    $sql = 'INSERT INTO ' . K_TABLE_TEST_USER . ' (
		testuser_test_id,
		testuser_user_id,
		testuser_status,
		testuser_creation_time,
		testuser_comment
		) VALUES (
		' . $test_id . ',
		' . $user_id . ',
		4,
		\'' . $date . '\',
		\'OMR\'
		)';
    if (!($r = F_db_query($sql, $db))) {
        F_display_db_error(false);
        return false;
    } else {
        // get inserted ID
        $testuser_id = F_db_insert_id($db, K_TABLE_TEST_USER, 'testuser_id');
    }
    // 3. create test log entries
    $num_questions = count($omr_testdata) - 1;
    // for each question on array
    for ($q = 1; $q <= $num_questions; ++$q) {
        $question_id = intval($omr_testdata[$q][0]);
        $num_answers = count($omr_testdata[$q][1]);
        // get question data
        $sqlq = 'SELECT question_type, question_difficulty FROM ' . K_TABLE_QUESTIONS . ' WHERE question_id=' . $question_id . ' LIMIT 1';
        if ($rq = F_db_query($sqlq, $db)) {
            if ($mq = F_db_fetch_array($rq)) {
                // question scores
                $question_right_score = $testdata['test_score_right'] * $mq['question_difficulty'];
                $question_wrong_score = $testdata['test_score_wrong'] * $mq['question_difficulty'];
                $question_unanswered_score = $testdata['test_score_unanswered'] * $mq['question_difficulty'];
                // add question
                $sqll = 'INSERT INTO ' . K_TABLE_TESTS_LOGS . ' (
					testlog_testuser_id,
					testlog_question_id,
					testlog_score,
					testlog_creation_time,
					testlog_display_time,
					testlog_reaction_time,
					testlog_order,
					testlog_num_answers
					) VALUES (
					' . $testuser_id . ',
					' . $question_id . ',
					' . $question_unanswered_score . ',
					\'' . $date . '\',
					\'' . $date . '\',
					1,
					' . $q . ',
					' . $num_answers . '
					)';
                if (!($rl = F_db_query($sqll, $db))) {
                    F_display_db_error(false);
                    return false;
                }
                $testlog_id = F_db_insert_id($db, K_TABLE_TESTS_LOGS, 'testlog_id');
                // set initial question score
                if ($mq['question_type'] == 1) {
                    // MCSA
                    $qscore = $question_unanswered_score;
                } else {
                    // MCMA
                    $qscore = 0;
                }
                $unanswered = true;
                // for each question on array
                for ($a = 1; $a <= $num_answers; ++$a) {
                    $answer_id = intval($omr_testdata[$q][1][$a]);
                    if (isset($omr_answers[$q][$a])) {
                        $answer_selected = $omr_answers[$q][$a];
                        //-1, 0, 1
                    } else {
                        $answer_selected = -1;
                    }
                    // add answer
                    $sqli = 'INSERT INTO ' . K_TABLE_LOG_ANSWER . ' (
						logansw_testlog_id,
						logansw_answer_id,
						logansw_selected,
						logansw_order
						) VALUES (
						' . $testlog_id . ',
						' . $answer_id . ',
						' . $answer_selected . ',
						' . $a . '
						)';
                    if (!($ri = F_db_query($sqli, $db))) {
                        F_display_db_error(false);
                        return false;
                    }
                    // calculate question score
                    if ($mq['question_type'] < 3) {
                        // MCSA or MCMA
                        // check if the answer is right
                        $answer_isright = false;
                        $sqla = 'SELECT answer_isright FROM ' . K_TABLE_ANSWERS . ' WHERE answer_id=' . $answer_id . ' LIMIT 1';
                        if ($ra = F_db_query($sqla, $db)) {
                            if ($ma = F_db_fetch_array($ra)) {
                                $answer_isright = F_getBoolean($ma['answer_isright']);
                                switch ($mq['question_type']) {
                                    case 1:
                                        // MCSA - Multiple Choice Single Answer
                                        if ($answer_selected == 1) {
                                            $unanswered = false;
                                            if ($answer_isright) {
                                                $qscore = $question_right_score;
                                            } else {
                                                $qscore = $question_wrong_score;
                                            }
                                        }
                                        break;
                                    case 2:
                                        // MCMA - Multiple Choice Multiple Answer
                                        if ($answer_selected == -1) {
                                            $qscore += $question_unanswered_score;
                                        } elseif ($answer_selected == 0) {
                                            $unanswered = false;
                                            if ($answer_isright) {
                                                $qscore += $question_wrong_score;
                                            } else {
                                                $qscore += $question_right_score;
                                            }
                                        } elseif ($answer_selected == 1) {
                                            $unanswered = false;
                                            if ($answer_isright) {
                                                $qscore += $question_right_score;
                                            } else {
                                                $qscore += $question_wrong_score;
                                            }
                                        }
                                        break;
                                }
                            }
                        } else {
                            F_display_db_error(false);
                            return false;
                        }
                    }
                }
                // end for each answer
                if ($mq['question_type'] == 2) {
                    // MCMA
                    // normalize score
                    if (F_getBoolean($testdata['test_mcma_partial_score'])) {
                        // use partial scoring for MCMA and ORDER questions
                        $qscore = round($qscore / $num_answers, 3);
                    } else {
                        // all-or-nothing points
                        if ($qscore >= $question_right_score * $num_answers) {
                            // right
                            $qscore = $question_right_score;
                        } elseif ($qscore == $question_unanswered_score * $num_answers) {
                            // unanswered
                            $qscore = $question_unanswered_score;
                        } else {
                            // wrong
                            $qscore = $question_wrong_score;
                        }
                    }
                }
                if ($unanswered) {
                    $change_time = '';
                } else {
                    $change_time = $dateanswers;
                }
                // update question score
                $sqll = 'UPDATE ' . K_TABLE_TESTS_LOGS . ' SET
					testlog_score=' . $qscore . ',
					testlog_change_time=' . F_empty_to_null($change_time) . ',
					testlog_reaction_time=1000
					WHERE testlog_id=' . $testlog_id . '';
                if (!($rl = F_db_query($sqll, $db))) {
                    F_display_db_error();
                    return false;
                }
            }
        } else {
            F_display_db_error(false);
            return false;
        }
    }
    // end for each question
    return true;
}
    echo '<textarea cols="50" rows="10" name="answer_explanation" id="answer_explanation" onselect="FJ_update_selection(document.getElementById(\'form_answereditor\').answer_explanation)" title="' . $l['h_explanation'] . '">' . htmlspecialchars($answer_explanation, ENT_NOQUOTES, $l['a_meta_charset']) . '</textarea>' . K_NEWLINE;
    echo '<br />' . K_NEWLINE;
    echo tcecodeEditorTagButtons('form_answereditor', 'answer_explanation', 1);
    echo '</span>' . K_NEWLINE;
    echo '</div>' . K_NEWLINE;
}
echo getFormRowCheckBox('answer_isright', $l['w_right'], $l['h_answer_isright'], '', 1, $answer_isright, false, '');
echo getFormRowCheckBox('answer_enabled', $l['w_enabled'], $l['h_enabled'], '', 1, $answer_enabled, false, '');
echo '<div class="row">' . K_NEWLINE;
echo '<span class="label">' . K_NEWLINE;
echo '<label for="answer_position">' . $l['w_position'] . '</label>' . K_NEWLINE;
echo '</span>' . K_NEWLINE;
echo '<span class="formw">' . K_NEWLINE;
echo '<select name="answer_position" id="answer_position" size="0" title="' . $l['h_position'] . '">' . K_NEWLINE;
if (isset($answer_id) and $answer_id > 0) {
    $max_position = 1 + F_count_rows(K_TABLE_ANSWERS, 'WHERE answer_question_id=' . $answer_question_id . ' AND answer_position>0 AND answer_id<>' . $answer_id . '');
} else {
    $max_position = 0;
}
echo '<option value="0">&nbsp;</option>' . K_NEWLINE;
for ($pos = 1; $pos <= $max_position; ++$pos) {
    echo '<option value="' . $pos . '"';
    if ($pos == $answer_position) {
        echo ' selected="selected"';
    }
    echo '>' . $pos . '</option>' . K_NEWLINE;
}
echo '<option value="' . ($max_position + 1) . '" style="color:#ff0000">' . ($max_position + 1) . '</option>' . K_NEWLINE;
echo '</select>' . K_NEWLINE;
echo '<input type="hidden" name="max_position" id="max_position" value="' . $max_position . '" />' . K_NEWLINE;
echo '</span>' . K_NEWLINE;
/**
 * Display user selection XHTML table.
 * @author Nicola Asuni
 * @since 2001-09-13
 * @param $order_field (string) order by column name
 * @param $orderdir (int) oreder direction
 * @param $firstrow (int) number of first row to display
 * @param $rowsperpage (int) number of rows per page
 * @param $group_id (int) id of the group (default = 0 = no specific group selected)
 * @param $andwhere (string) additional SQL WHERE query conditions
 * @param $searchterms (string) search terms
 * @return false in case of empty database, true otherwise
 */
function F_show_select_user($order_field, $orderdir, $firstrow, $rowsperpage, $group_id = 0, $andwhere = '', $searchterms = '')
{
    global $l, $db;
    require_once '../config/tce_config.php';
    require_once '../../shared/code/tce_functions_page.php';
    require_once '../../shared/code/tce_functions_form.php';
    $filter = '';
    if ($l['a_meta_dir'] == 'rtl') {
        $txtalign = 'right';
        $numalign = 'left';
    } else {
        $txtalign = 'left';
        $numalign = 'right';
    }
    $order_field = F_escape_sql($order_field);
    $orderdir = intval($orderdir);
    $firstrow = intval($firstrow);
    $rowsperpage = intval($rowsperpage);
    $group_id = intval($group_id);
    if (empty($order_field) or !in_array($order_field, array('user_id', 'user_name', 'user_password', 'user_email', 'user_regdate', 'user_ip', 'user_firstname', 'user_lastname', 'user_regnumber', 'user_level', 'user_verifycode'))) {
        $order_field = 'user_lastname,user_firstname';
    }
    if ($orderdir == 0) {
        $nextorderdir = 1;
        $full_order_field = $order_field;
    } else {
        $nextorderdir = 0;
        $full_order_field = $order_field . ' DESC';
    }
    if (!F_count_rows(K_TABLE_USERS)) {
        // if the table is void (no items) display message
        F_print_error('MESSAGE', $l['m_databasempty']);
        return FALSE;
    }
    $wherequery = '';
    if ($group_id > 0) {
        $wherequery = ', ' . K_TABLE_USERGROUP . ' WHERE user_id=usrgrp_user_id	AND usrgrp_group_id=' . $group_id . '';
        $filter .= '&amp;group_id=' . $group_id . '';
    }
    if (empty($wherequery)) {
        $wherequery = ' WHERE';
    } else {
        $wherequery .= ' AND';
    }
    $wherequery .= ' (user_id>1)';
    if ($_SESSION['session_user_level'] < K_AUTH_ADMINISTRATOR) {
        // filter for level
        $wherequery .= ' AND ((user_level<' . $_SESSION['session_user_level'] . ') OR (user_id=' . $_SESSION['session_user_id'] . '))';
        // filter for groups
        $wherequery .= ' AND user_id IN (SELECT tb.usrgrp_user_id
			FROM ' . K_TABLE_USERGROUP . ' AS ta, ' . K_TABLE_USERGROUP . ' AS tb
			WHERE ta.usrgrp_group_id=tb.usrgrp_group_id
				AND ta.usrgrp_user_id=' . intval($_SESSION['session_user_id']) . '
				AND tb.usrgrp_user_id=user_id)';
    }
    if (!empty($andwhere)) {
        $wherequery .= ' AND (' . $andwhere . ')';
    }
    $sql = 'SELECT * FROM ' . K_TABLE_USERS . $wherequery . ' ORDER BY ' . $full_order_field;
    if (K_DATABASE_TYPE == 'ORACLE') {
        $sql = 'SELECT * FROM (' . $sql . ') WHERE rownum BETWEEN ' . $firstrow . ' AND ' . ($firstrow + $rowsperpage) . '';
    } else {
        $sql .= ' LIMIT ' . $rowsperpage . ' OFFSET ' . $firstrow . '';
    }
    if ($r = F_db_query($sql, $db)) {
        if ($m = F_db_fetch_array($r)) {
            // -- Table structure with links:
            echo '<div class="container">';
            echo '<table class="userselect">' . K_NEWLINE;
            // table header
            echo '<tr>' . K_NEWLINE;
            echo '<th>&nbsp;</th>' . K_NEWLINE;
            if (strlen($searchterms) > 0) {
                $filter .= '&amp;searchterms=' . urlencode($searchterms);
            }
            echo F_select_table_header_element('user_name', $nextorderdir, $l['h_login_name'], $l['w_user'], $order_field, $filter);
            echo F_select_table_header_element('user_lastname', $nextorderdir, $l['h_lastname'], $l['w_lastname'], $order_field, $filter);
            echo F_select_table_header_element('user_firstname', $nextorderdir, $l['h_firstname'], $l['w_firstname'], $order_field, $filter);
            echo F_select_table_header_element('user_regnumber', $nextorderdir, $l['h_regcode'], $l['w_regcode'], $order_field, $filter);
            echo F_select_table_header_element('user_level', $nextorderdir, $l['h_level'], $l['w_level'], $order_field, $filter);
            echo F_select_table_header_element('user_regdate', $nextorderdir, $l['h_regdate'], $l['w_regdate'], $order_field, $filter);
            echo '<th title="' . $l['h_group_name'] . '">' . $l['w_groups'] . '</th>' . K_NEWLINE;
            echo '</tr>' . K_NEWLINE;
            $itemcount = 0;
            do {
                $itemcount++;
                echo '<tr>' . K_NEWLINE;
                echo '<td>';
                echo '<input type="checkbox" name="userid' . $itemcount . '" id="userid' . $itemcount . '" value="' . $m['user_id'] . '" title="' . $l['w_select'] . '"';
                if (isset($_REQUEST['checkall']) and $_REQUEST['checkall'] == 1) {
                    echo ' checked="checked"';
                }
                echo ' />';
                echo '</td>' . K_NEWLINE;
                echo '<td style="text-align:' . $txtalign . ';">&nbsp;<a href="tce_edit_user.php?user_id=' . $m['user_id'] . '" title="' . $l['w_edit'] . '">' . htmlspecialchars($m['user_name'], ENT_NOQUOTES, $l['a_meta_charset']) . '</a></td>' . K_NEWLINE;
                echo '<td style="text-align:' . $txtalign . ';">&nbsp;' . htmlspecialchars($m['user_lastname'], ENT_NOQUOTES, $l['a_meta_charset']) . '</td>' . K_NEWLINE;
                echo '<td style="text-align:' . $txtalign . ';">&nbsp;' . htmlspecialchars($m['user_firstname'], ENT_NOQUOTES, $l['a_meta_charset']) . '</td>' . K_NEWLINE;
                echo '<td style="text-align:' . $txtalign . ';">&nbsp;' . htmlspecialchars($m['user_regnumber'], ENT_NOQUOTES, $l['a_meta_charset']) . '</td>' . K_NEWLINE;
                echo '<td>&nbsp;' . $m['user_level'] . '</td>' . K_NEWLINE;
                echo '<td>&nbsp;' . htmlspecialchars($m['user_regdate'], ENT_NOQUOTES, $l['a_meta_charset']) . '</td>' . K_NEWLINE;
                // comma separated list of user's groups
                $grp = '';
                $sqlg = 'SELECT *
					FROM ' . K_TABLE_GROUPS . ', ' . K_TABLE_USERGROUP . '
					WHERE usrgrp_group_id=group_id
						AND usrgrp_user_id=' . $m['user_id'] . '
					ORDER BY group_name';
                if ($rg = F_db_query($sqlg, $db)) {
                    while ($mg = F_db_fetch_array($rg)) {
                        $grp .= $mg['group_name'] . ', ';
                    }
                } else {
                    F_display_db_error();
                }
                echo '<td style="text-align:' . $txtalign . ';">&nbsp;' . htmlspecialchars(substr($grp, 0, -2), ENT_NOQUOTES, $l['a_meta_charset']) . '</td>' . K_NEWLINE;
                echo '</tr>' . K_NEWLINE;
            } while ($m = F_db_fetch_array($r));
            echo '</table>' . K_NEWLINE;
            echo '<br />' . K_NEWLINE;
            echo '<input type="hidden" name="order_field" id="order_field" value="' . $order_field . '" />' . K_NEWLINE;
            echo '<input type="hidden" name="orderdir" id="orderdir" value="' . $orderdir . '" />' . K_NEWLINE;
            echo '<input type="hidden" name="firstrow" id="firstrow" value="' . $firstrow . '" />' . K_NEWLINE;
            echo '<input type="hidden" name="rowsperpage" id="rowsperpage" value="' . $rowsperpage . '" />' . K_NEWLINE;
            // check/uncheck all options
            echo '<span dir="ltr">';
            echo '<input type="radio" name="checkall" id="checkall1" value="1" onclick="document.getElementById(\'form_userselect\').submit()" />';
            echo '<label for="checkall1">' . $l['w_check_all'] . '</label> ';
            echo '<input type="radio" name="checkall" id="checkall0" value="0" onclick="document.getElementById(\'form_userselect\').submit()" />';
            echo '<label for="checkall0">' . $l['w_uncheck_all'] . '</label>';
            echo '</span>' . K_NEWLINE;
            echo '<br />' . K_NEWLINE;
            echo '<strong style="margin:5px">' . $l['m_with_selected'] . '</strong>' . K_NEWLINE;
            echo '<ul style="margin:0">';
            if ($_SESSION['session_user_level'] >= K_AUTH_DELETE_USERS) {
                // delete user
                echo '<li>';
                F_submit_button('delete', $l['w_delete'], $l['h_delete']);
                echo '</li>' . K_NEWLINE;
            }
            if ($_SESSION['session_user_level'] >= K_AUTH_ADMIN_GROUPS) {
                echo '<li>';
                // add/delete group
                echo F_user_group_select('new_group_id');
                F_submit_button('addgroup', $l['w_add'], $l['w_add']);
                if ($_SESSION['session_user_level'] >= K_AUTH_DELETE_GROUPS) {
                    F_submit_button('delgroup', $l['w_delete'], $l['h_delete']);
                }
                echo '</li>' . K_NEWLINE;
                if ($_SESSION['session_user_level'] >= K_AUTH_MOVE_GROUPS) {
                    // move group
                    echo '<li>';
                    if ($l['a_meta_dir'] == 'rtl') {
                        $arr = '&larr;';
                    } else {
                        $arr = '&rarr;';
                    }
                    echo F_user_group_select('from_group_id');
                    echo $arr;
                    echo F_user_group_select('to_group_id');
                    F_submit_button('move', $l['w_move'], $l['w_move']);
                    echo '</li>' . K_NEWLINE;
                }
            }
            echo '</ul>' . K_NEWLINE;
            echo '<div class="row"><hr /></div>' . K_NEWLINE;
            // ---------------------------------------------------------------
            // -- page jumper (menu for successive pages)
            if ($rowsperpage > 0) {
                $sql = 'SELECT count(*) AS total FROM ' . K_TABLE_USERS . '' . $wherequery . '';
                if (!empty($order_field)) {
                    $param_array = '&amp;order_field=' . urlencode($order_field) . '';
                }
                if (!empty($orderdir)) {
                    $param_array .= '&amp;orderdir=' . $orderdir . '';
                }
                if (!empty($group_id)) {
                    $param_array .= '&amp;group_id=' . $group_id . '';
                }
                if (!empty($searchterms)) {
                    $param_array .= '&amp;searchterms=' . urlencode($searchterms) . '';
                }
                $param_array .= '&amp;submitted=1';
                F_show_page_navigator($_SERVER['SCRIPT_NAME'], $sql, $firstrow, $rowsperpage, $param_array);
            }
            echo '<div class="row">' . K_NEWLINE;
            echo '<br />';
            //echo '<a href="tce_xml_users.php" class="xmlbutton" title="'.$l['h_xml_export'].'">XML</a> ';
            //echo '<a href="tce_csv_users.php" class="xmlbutton" title="'.$l['h_csv_export'].'">CSV</a>';
            echo '</div>' . K_NEWLINE;
            echo '<div class="pagehelp">' . $l['hp_select_users'] . '</div>' . K_NEWLINE;
            echo '</div>' . K_NEWLINE;
        } else {
            F_print_error('MESSAGE', $l['m_search_void']);
        }
    } else {
        F_display_db_error();
    }
    return TRUE;
}
/**
* Returns raw statistic array for the selected test.
* @param $test_id (int) test ID.
* @param $group_id (int) group ID - if greater than zero, filter stats for the specified user group.
* @param $user_id (int) user ID - if greater than zero, filter stats for the specified user.
* @param $startdate (int) start date ID - if greater than zero, filter stats for the specified starting date
* @param $enddate (int) end date ID - if greater than zero, filter stats for the specified ending date
* @param $testuser_id (int) test-user ID - if greater than zero, filter stats for the specified test-user.
* @param $data (array) Array of existing data to be merged with the current one.
* @param $pubmode (boolean) If true filter the results for the public interface.
* return $data array containing test statistics.
*/
function F_getRawTestStat($test_id, $group_id = 0, $user_id = 0, $startdate = 0, $enddate = 0, $testuser_id = 0, $data = array(), $pubmode = false)
{
    require_once '../config/tce_config.php';
    require_once '../../shared/code/tce_functions_authorization.php';
    require_once '../../shared/code/tce_functions_test.php';
    global $db, $l;
    $test_id = intval($test_id);
    $group_id = intval($group_id);
    $user_id = intval($user_id);
    $testuser_id = intval($testuser_id);
    // query to calculate total number of questions
    $sqltot = K_TABLE_TEST_USER . ', ' . K_TABLE_TESTS_LOGS;
    $sqltb = K_TABLE_TEST_USER . ', ' . K_TABLE_TESTS_LOGS . ', ' . K_TABLE_ANSWERS . ', ' . K_TABLE_LOG_ANSWER;
    $sqlm = K_TABLE_TEST_USER . ', ' . K_TABLE_TESTS_LOGS . ', ' . K_TABLE_QUESTIONS . ', ' . K_TABLE_SUBJECTS . ', ' . K_TABLE_MODULES . '';
    // apply filters
    $sqlw = 'WHERE testlog_testuser_id=testuser_id';
    $sqlansw = 'WHERE logansw_answer_id=answer_id AND logansw_testlog_id=testlog_id AND testlog_testuser_id=testuser_id';
    if ($test_id > 0) {
        $sqlw .= ' AND testuser_test_id=' . $test_id . '';
        $sqlansw .= ' AND testuser_test_id=' . $test_id . '';
    } elseif ($pubmode) {
        $test_ids_results = F_getTestIDResults($test_id, $user_id);
        $sqlw .= ' AND testuser_test_id IN (' . $test_ids_results . ')';
        $sqlansw .= ' AND testuser_test_id IN (' . $test_ids_results . ')';
    }
    if ($user_id > 0) {
        $sqltot .= ', ' . K_TABLE_USERS;
        $sqltb .= ', ' . K_TABLE_USERS;
        $sqlm .= ', ' . K_TABLE_USERS;
        $sqlw .= ' AND testuser_user_id=user_id AND user_id=' . $user_id . '';
        $sqlansw .= ' AND testuser_user_id=user_id AND user_id=' . $user_id . '';
        if ($testuser_id > 0) {
            $sqlw .= ' AND testuser_id=' . $testuser_id . '';
            $sqlansw .= ' AND testuser_id=' . $testuser_id . '';
        }
    } elseif ($group_id > 0) {
        $sqltot .= ', ' . K_TABLE_USERS . ', ' . K_TABLE_USERGROUP;
        $sqltb .= ', ' . K_TABLE_USERS . ', ' . K_TABLE_USERGROUP;
        $sqlm .= ', ' . K_TABLE_USERS . ', ' . K_TABLE_USERGROUP;
        $sqlw .= ' AND testuser_user_id=user_id AND usrgrp_user_id=user_id AND usrgrp_group_id=' . $group_id . '';
        $sqlansw .= ' AND testuser_user_id=user_id AND usrgrp_user_id=user_id AND usrgrp_group_id=' . $group_id . '';
    }
    if (!empty($startdate)) {
        $startdate_time = strtotime($startdate);
        $startdate = date(K_TIMESTAMP_FORMAT, $startdate_time);
        $sqlw .= ' AND testuser_creation_time>=\'' . $startdate . '\'';
        $sqlansw .= ' AND testuser_creation_time>=\'' . $startdate . '\'';
    }
    if (!empty($enddate)) {
        $enddate_time = strtotime($enddate);
        $enddate = date(K_TIMESTAMP_FORMAT, $enddate_time);
        $sqlw .= ' AND testuser_creation_time<=\'' . $enddate . '\'';
        $sqlansw .= ' AND testuser_creation_time<=\'' . $enddate . '\'';
    }
    // check if a specific test is selected or not
    if ($test_id == 0) {
        $test_ids = array();
        $sqlt = 'SELECT testuser_test_id FROM ' . $sqltot . ' ' . $sqlw . ' GROUP BY testuser_test_id ORDER BY testuser_test_id';
        if ($rt = F_db_query($sqlt, $db)) {
            while ($mt = F_db_fetch_assoc($rt)) {
                // check user's authorization
                if (F_isAuthorizedUser(K_TABLE_TESTS, 'test_id', $mt['testuser_test_id'], 'test_user_id')) {
                    $test_ids[] = $mt['testuser_test_id'];
                }
            }
        } else {
            F_display_db_error();
        }
        foreach ($test_ids as $tid) {
            // select test IDs
            $data = F_getRawTestStat($tid, $group_id, $user_id, $startdate, $enddate, $testuser_id, $data);
        }
        return $data;
    }
    $testdata = F_getTestData($test_id);
    // array to be returned
    if (!isset($data['qstats'])) {
        // total number of questions
        $data['qstats'] = array('recurrence' => 0, 'recurrence_perc' => 0, 'average_score' => 0, 'average_score_perc' => 0, 'average_time' => 0, 'right' => 0, 'right_perc' => 0, 'wrong' => 0, 'wrong_perc' => 0, 'unanswered' => 0, 'unanswered_perc' => 0, 'undisplayed' => 0, 'undisplayed_perc' => 0, 'unrated' => 0, 'unrated_perc' => 0, 'qnum' => 0, 'module' => array());
    }
    $sql = 'SELECT
		module_id,
		subject_id,
		question_id,
		module_name,
		subject_name,
		subject_description,
		question_description,';
    if ($user_id > 0 and $testuser_id > 0) {
        $sql .= ' testlog_score,
			testlog_user_ip,
			testlog_display_time,
			testlog_change_time,
			testlog_reaction_time,
			testlog_answer_text,
			question_type,
			question_explanation,';
    }
    $sql .= ' COUNT(question_id) AS recurrence,
		AVG(testlog_score) AS average_score,
		AVG(testlog_change_time - testlog_display_time) AS average_time,
		MIN(question_type) AS question_type,
		MIN(question_difficulty) AS question_difficulty';
    $sql .= ' FROM ' . $sqlm;
    $sql .= ' WHERE testlog_testuser_id=testuser_id AND question_id=testlog_question_id AND subject_id=question_subject_id AND module_id=subject_module_id';
    if ($test_id > 0) {
        $sql .= ' AND testuser_test_id=' . $test_id . '';
    }
    if ($testuser_id > 0) {
        $sql .= ' AND testuser_id=' . $testuser_id . '';
    }
    if ($user_id > 0) {
        $sql .= ' AND testuser_user_id=user_id AND user_id=' . $user_id . '';
    } elseif ($group_id > 0) {
        $sql .= ' AND testuser_user_id=user_id AND usrgrp_user_id=user_id AND usrgrp_group_id=' . $group_id . '';
    }
    if (!empty($startdate)) {
        $sql .= ' AND testuser_creation_time>=\'' . $startdate . '\'';
    }
    if (!empty($enddate)) {
        $sql .= ' AND testuser_creation_time<=\'' . $enddate . '\'';
    }
    $sql .= ' GROUP BY module_id, subject_id, question_id, module_name, subject_name, subject_description, question_description';
    if ($user_id > 0 and $testuser_id > 0) {
        $sql .= ', testlog_score, testlog_user_ip, testlog_display_time, testlog_change_time, testlog_reaction_time, testlog_answer_text, question_type, question_explanation';
    } else {
        $sql .= ' ORDER BY module_name, subject_name, question_description';
    }
    if ($r = F_db_query($sql, $db)) {
        while ($m = F_db_fetch_array($r)) {
            if (!isset($data['qstats']['module']['\'' . $m['module_id'] . '\''])) {
                $data['qstats']['module']['\'' . $m['module_id'] . '\''] = array('id' => $m['module_id'], 'name' => $m['module_name'], 'recurrence' => 0, 'recurrence_perc' => 0, 'average_score' => 0, 'average_score_perc' => 0, 'average_time' => 0, 'right' => 0, 'right_perc' => 0, 'wrong' => 0, 'wrong_perc' => 0, 'unanswered' => 0, 'unanswered_perc' => 0, 'undisplayed' => 0, 'undisplayed_perc' => 0, 'unrated' => 0, 'unrated_perc' => 0, 'qnum' => 0, 'subject' => array());
            }
            if (!isset($data['qstats']['module']['\'' . $m['module_id'] . '\'']['subject']['\'' . $m['subject_id'] . '\''])) {
                $data['qstats']['module']['\'' . $m['module_id'] . '\'']['subject']['\'' . $m['subject_id'] . '\''] = array('id' => $m['subject_id'], 'name' => $m['subject_name'], 'description' => $m['subject_description'], 'recurrence' => 0, 'recurrence_perc' => 0, 'average_score' => 0, 'average_score_perc' => 0, 'average_time' => 0, 'right' => 0, 'right_perc' => 0, 'wrong' => 0, 'wrong_perc' => 0, 'unanswered' => 0, 'unanswered_perc' => 0, 'undisplayed' => 0, 'undisplayed_perc' => 0, 'unrated' => 0, 'unrated_perc' => 0, 'qnum' => 0, 'question' => array());
            }
            $question_max_score = $testdata['test_score_right'] * $m['question_difficulty'];
            $question_half_score = $question_max_score / 2;
            $qright = F_count_rows($sqltot, $sqlw . ' AND testlog_question_id=' . $m['question_id'] . ' AND testlog_score>' . $question_half_score . '');
            $qwrong = F_count_rows($sqltot, $sqlw . ' AND testlog_question_id=' . $m['question_id'] . ' AND testlog_score<=' . $question_half_score . '');
            $qunanswered = F_count_rows($sqltot, $sqlw . ' AND testlog_question_id=' . $m['question_id'] . ' AND testlog_change_time IS NULL');
            $qundisplayed = F_count_rows($sqltot, $sqlw . ' AND testlog_question_id=' . $m['question_id'] . ' AND testlog_display_time IS NULL');
            $qunrated = F_count_rows($sqltot, $sqlw . ' AND testlog_question_id=' . $m['question_id'] . ' AND testlog_score IS NULL');
            if (stripos($m['average_time'], ':') !== FALSE) {
                // PostgreSQL returns formatted time, while MySQL returns the number of seconds
                $m['average_time'] = strtotime($m['average_time']);
            }
            $num_all_answers = F_count_rows($sqltb, $sqlansw . ' AND testlog_question_id=' . $m['question_id']);
            if (!isset($data['qstats']['module']['\'' . $m['module_id'] . '\'']['subject']['\'' . $m['subject_id'] . '\'']['question']['\'' . $m['question_id'] . '\''])) {
                $data['qstats']['module']['\'' . $m['module_id'] . '\'']['subject']['\'' . $m['subject_id'] . '\'']['question']['\'' . $m['question_id'] . '\''] = array('id' => $m['question_id'], 'description' => $m['question_description'], 'type' => $m['question_type'], 'difficulty' => $m['question_difficulty'], 'recurrence' => 0, 'recurrence_perc' => 0, 'average_score' => 0, 'average_score_perc' => 0, 'average_time' => 0, 'right' => 0, 'right_perc' => 0, 'wrong' => 0, 'wrong_perc' => 0, 'unanswered' => 0, 'unanswered_perc' => 0, 'undisplayed' => 0, 'undisplayed_perc' => 0, 'unrated' => 0, 'unrated_perc' => 0, 'qnum' => 0, 'anum' => 0, 'answer' => array());
            }
            // average score ratio
            if ($question_max_score > 0) {
                $average_score_perc = $m['average_score'] / $question_max_score;
            } else {
                $average_score_perc = 0;
            }
            // sum values for questions
            $data['qstats']['module']['\'' . $m['module_id'] . '\'']['subject']['\'' . $m['subject_id'] . '\'']['question']['\'' . $m['question_id'] . '\'']['qnum'] += 1;
            $data['qstats']['module']['\'' . $m['module_id'] . '\'']['subject']['\'' . $m['subject_id'] . '\'']['question']['\'' . $m['question_id'] . '\'']['recurrence'] += $m['recurrence'];
            $data['qstats']['module']['\'' . $m['module_id'] . '\'']['subject']['\'' . $m['subject_id'] . '\'']['question']['\'' . $m['question_id'] . '\'']['average_score'] += $m['average_score'];
            $data['qstats']['module']['\'' . $m['module_id'] . '\'']['subject']['\'' . $m['subject_id'] . '\'']['question']['\'' . $m['question_id'] . '\'']['average_score_perc'] += $average_score_perc;
            $data['qstats']['module']['\'' . $m['module_id'] . '\'']['subject']['\'' . $m['subject_id'] . '\'']['question']['\'' . $m['question_id'] . '\'']['average_time'] += $m['average_time'];
            $data['qstats']['module']['\'' . $m['module_id'] . '\'']['subject']['\'' . $m['subject_id'] . '\'']['question']['\'' . $m['question_id'] . '\'']['right'] += $qright;
            $data['qstats']['module']['\'' . $m['module_id'] . '\'']['subject']['\'' . $m['subject_id'] . '\'']['question']['\'' . $m['question_id'] . '\'']['wrong'] += $qwrong;
            $data['qstats']['module']['\'' . $m['module_id'] . '\'']['subject']['\'' . $m['subject_id'] . '\'']['question']['\'' . $m['question_id'] . '\'']['unanswered'] += $qunanswered;
            $data['qstats']['module']['\'' . $m['module_id'] . '\'']['subject']['\'' . $m['subject_id'] . '\'']['question']['\'' . $m['question_id'] . '\'']['undisplayed'] += $qundisplayed;
            $data['qstats']['module']['\'' . $m['module_id'] . '\'']['subject']['\'' . $m['subject_id'] . '\'']['question']['\'' . $m['question_id'] . '\'']['unrated'] += $qunrated;
            $data['qstats']['module']['\'' . $m['module_id'] . '\'']['subject']['\'' . $m['subject_id'] . '\'']['question']['\'' . $m['question_id'] . '\'']['anum'] += $num_all_answers;
            // sum values for subject
            $data['qstats']['module']['\'' . $m['module_id'] . '\'']['subject']['\'' . $m['subject_id'] . '\'']['qnum'] += 1;
            $data['qstats']['module']['\'' . $m['module_id'] . '\'']['subject']['\'' . $m['subject_id'] . '\'']['recurrence'] += $m['recurrence'];
            $data['qstats']['module']['\'' . $m['module_id'] . '\'']['subject']['\'' . $m['subject_id'] . '\'']['average_score'] += $m['average_score'];
            $data['qstats']['module']['\'' . $m['module_id'] . '\'']['subject']['\'' . $m['subject_id'] . '\'']['average_score_perc'] += $average_score_perc;
            $data['qstats']['module']['\'' . $m['module_id'] . '\'']['subject']['\'' . $m['subject_id'] . '\'']['average_time'] += $m['average_time'];
            $data['qstats']['module']['\'' . $m['module_id'] . '\'']['subject']['\'' . $m['subject_id'] . '\'']['right'] += $qright;
            $data['qstats']['module']['\'' . $m['module_id'] . '\'']['subject']['\'' . $m['subject_id'] . '\'']['wrong'] += $qwrong;
            $data['qstats']['module']['\'' . $m['module_id'] . '\'']['subject']['\'' . $m['subject_id'] . '\'']['unanswered'] += $qunanswered;
            $data['qstats']['module']['\'' . $m['module_id'] . '\'']['subject']['\'' . $m['subject_id'] . '\'']['undisplayed'] += $qundisplayed;
            $data['qstats']['module']['\'' . $m['module_id'] . '\'']['subject']['\'' . $m['subject_id'] . '\'']['unrated'] += $qunrated;
            // sum values for module
            $data['qstats']['module']['\'' . $m['module_id'] . '\'']['qnum'] += 1;
            $data['qstats']['module']['\'' . $m['module_id'] . '\'']['recurrence'] += $m['recurrence'];
            $data['qstats']['module']['\'' . $m['module_id'] . '\'']['average_score'] += $m['average_score'];
            $data['qstats']['module']['\'' . $m['module_id'] . '\'']['average_score_perc'] += $average_score_perc;
            $data['qstats']['module']['\'' . $m['module_id'] . '\'']['average_time'] += $m['average_time'];
            $data['qstats']['module']['\'' . $m['module_id'] . '\'']['right'] += $qright;
            $data['qstats']['module']['\'' . $m['module_id'] . '\'']['wrong'] += $qwrong;
            $data['qstats']['module']['\'' . $m['module_id'] . '\'']['unanswered'] += $qunanswered;
            $data['qstats']['module']['\'' . $m['module_id'] . '\'']['undisplayed'] += $qundisplayed;
            $data['qstats']['module']['\'' . $m['module_id'] . '\'']['unrated'] += $qunrated;
            // sum totals
            $data['qstats']['qnum'] += 1;
            $data['qstats']['recurrence'] += $m['recurrence'];
            $data['qstats']['average_score'] += $m['average_score'];
            $data['qstats']['average_score_perc'] += $average_score_perc;
            $data['qstats']['average_time'] += $m['average_time'];
            $data['qstats']['right'] += $qright;
            $data['qstats']['wrong'] += $qwrong;
            $data['qstats']['unanswered'] += $qunanswered;
            $data['qstats']['undisplayed'] += $qundisplayed;
            $data['qstats']['unrated'] += $qunrated;
            // get answer statistics
            $sqlaa = 'SELECT answer_id, answer_description, COUNT(answer_id) AS recurrence';
            if ($user_id > 0 and $testuser_id > 0) {
                $sqlaa .= ', logansw_position, logansw_selected, answer_isright, answer_position, answer_explanation';
            }
            $sqlaa .= ' FROM ' . $sqltb . '';
            $sqlaw = ' WHERE testlog_testuser_id=testuser_id
					AND logansw_testlog_id=testlog_id
					AND answer_id=logansw_answer_id
					AND answer_question_id=' . $m['question_id'] . '';
            if ($test_id > 0) {
                $sqlaw .= ' AND testuser_test_id=' . $test_id . '';
            }
            if ($user_id > 0) {
                $sqlaw .= ' AND testuser_user_id=' . $user_id . '';
            }
            if ($testuser_id > 0) {
                $sqlaw .= ' AND testuser_id=' . $testuser_id . '';
            }
            if ($user_id > 0) {
                $sqlaw .= ' AND testuser_user_id=user_id AND user_id=' . $user_id . '';
            } elseif ($group_id > 0) {
                $sqlaw .= ' AND testuser_user_id=user_id AND usrgrp_user_id=user_id AND usrgrp_group_id=' . $group_id . '';
            }
            if (!empty($startdate)) {
                $sql .= ' AND testuser_creation_time>=\'' . $startdate . '\'';
            }
            if (!empty($enddate)) {
                $sql .= ' AND testuser_creation_time<=\'' . $enddate . '\'';
            }
            $sqlab = ' GROUP BY answer_id, answer_description';
            if ($user_id > 0 and $testuser_id > 0) {
                $sqlab .= ', logansw_position, logansw_selected, answer_isright, answer_position, answer_explanation';
            }
            $sqlab .= ' ORDER BY answer_description';
            $sqla = $sqlaa . $sqlaw . $sqlab;
            if ($ra = F_db_query($sqla, $db)) {
                while ($ma = F_db_fetch_array($ra)) {
                    $aright = F_count_rows($sqltb, $sqlaw . ' AND answer_id=' . $ma['answer_id'] . ' AND ((answer_isright=\'0\' AND logansw_selected=0) OR (answer_isright=\'1\' AND logansw_selected=1) OR (answer_position IS NOT NULL AND logansw_position IS NOT NULL AND answer_position=logansw_position))');
                    $awrong = F_count_rows($sqltb, $sqlaw . ' AND answer_id=' . $ma['answer_id'] . ' AND ((answer_isright=\'0\' AND logansw_selected=1) OR (answer_isright=\'1\' AND logansw_selected=0) OR (answer_position IS NOT NULL AND answer_position!=logansw_position))');
                    $aunanswered = F_count_rows($sqltb, $sqlaw . ' AND answer_id=' . $ma['answer_id'] . ' AND logansw_selected=-1');
                    if (!isset($data['qstats']['module']['\'' . $m['module_id'] . '\'']['subject']['\'' . $m['subject_id'] . '\'']['question']['\'' . $m['question_id'] . '\'']['answer']['\'' . $ma['answer_id'] . '\''])) {
                        $data['qstats']['module']['\'' . $m['module_id'] . '\'']['subject']['\'' . $m['subject_id'] . '\'']['question']['\'' . $m['question_id'] . '\'']['answer']['\'' . $ma['answer_id'] . '\''] = array('id' => $ma['answer_id'], 'description' => $ma['answer_description'], 'recurrence' => 0, 'recurrence_perc' => 0, 'right' => 0, 'right_perc' => 0, 'wrong' => 0, 'wrong_perc' => 0, 'unanswered' => 0, 'unanswered_perc' => 0);
                    }
                    $data['qstats']['module']['\'' . $m['module_id'] . '\'']['subject']['\'' . $m['subject_id'] . '\'']['question']['\'' . $m['question_id'] . '\'']['answer']['\'' . $ma['answer_id'] . '\'']['recurrence'] += $ma['recurrence'];
                    $data['qstats']['module']['\'' . $m['module_id'] . '\'']['subject']['\'' . $m['subject_id'] . '\'']['question']['\'' . $m['question_id'] . '\'']['answer']['\'' . $ma['answer_id'] . '\'']['right'] += $aright;
                    $data['qstats']['module']['\'' . $m['module_id'] . '\'']['subject']['\'' . $m['subject_id'] . '\'']['question']['\'' . $m['question_id'] . '\'']['answer']['\'' . $ma['answer_id'] . '\'']['wrong'] += $awrong;
                    $data['qstats']['module']['\'' . $m['module_id'] . '\'']['subject']['\'' . $m['subject_id'] . '\'']['question']['\'' . $m['question_id'] . '\'']['answer']['\'' . $ma['answer_id'] . '\'']['unanswered'] += $aunanswered;
                }
            } else {
                F_display_db_error();
            }
        }
    } else {
        F_display_db_error();
    }
    return $data;
}
Example #13
0
/**
 * Export all question statistics of the selected test to XML.
 * @author Nicola Asuni
 * @since 2010-05-10
 * @param $test_id (int) test ID
 * @return XML data
 */
function F_xml_export_question_stats($test_id)
{
    global $l, $db;
    require_once '../config/tce_config.php';
    require_once '../../shared/code/tce_authorization.php';
    require_once '../code/tce_functions_auth_sql.php';
    $boolean = array('false', 'true');
    $type = array('single', 'multiple', 'text', 'ordering');
    $xml = '';
    // XML data to be returned
    $xml .= '<' . '?xml version="1.0" encoding="UTF-8" ?' . '>' . K_NEWLINE;
    $xml .= '<tcexamquestionstats version="' . K_TCEXAM_VERSION . '">' . K_NEWLINE;
    $xml .= K_TAB . '<header';
    $xml .= ' lang="' . K_USER_LANG . '"';
    $xml .= ' date="' . date(K_TIMESTAMP_FORMAT) . '">' . K_NEWLINE;
    $xml .= K_TAB . '</header>' . K_NEWLINE;
    $xml .= K_TAB . '<body>' . K_NEWLINE;
    // get test data
    $testdata = F_getTestData($test_id);
    // get total number of questions for the selected test
    $num_questions = F_count_rows(K_TABLE_TESTS_LOGS . ', ' . K_TABLE_TEST_USER, 'WHERE testlog_testuser_id=testuser_id AND testuser_test_id=' . $test_id . '');
    // output questions stats
    $sqlr = 'SELECT
			question_id,
			COUNT(question_id) AS recurrence,
			AVG(testlog_score) AS average_score,
			AVG(testlog_change_time - testlog_display_time) AS average_time,
			min(question_difficulty) AS question_difficulty
		FROM ' . K_TABLE_TESTS_LOGS . ', ' . K_TABLE_TEST_USER . ', ' . K_TABLE_QUESTIONS . '
		WHERE testlog_testuser_id=testuser_id
			AND testlog_question_id=question_id
			AND testuser_test_id=' . $test_id . '
		GROUP BY question_id
		ORDER BY recurrence DESC,average_score DESC';
    if ($rr = F_db_query($sqlr, $db)) {
        while ($mr = F_db_fetch_array($rr)) {
            $xml .= K_TAB . K_TAB . '<question>' . K_NEWLINE;
            // get the question max score
            $question_max_score = $testdata['test_score_right'] * $mr['question_difficulty'];
            $qsttestdata = F_getQuestionTestStat($test_id, $mr['question_id']);
            $xml .= K_TAB . K_TAB . K_TAB . '<id>' . $mr['question_id'] . '</id>' . K_NEWLINE;
            $question_description = '';
            $sqlrq = 'SELECT question_description FROM ' . K_TABLE_QUESTIONS . ' WHERE question_id=' . $mr['question_id'] . '';
            if ($rrq = F_db_query($sqlrq, $db)) {
                if ($mrq = F_db_fetch_array($rrq)) {
                    $question_description = $mrq['question_description'];
                }
            } else {
                F_display_db_error();
            }
            $xml .= K_TAB . K_TAB . K_TAB . '<description>' . F_text_to_xml($question_description) . '</description>' . K_NEWLINE;
            $xml .= K_TAB . K_TAB . K_TAB . '<recurrence>' . $mr['recurrence'] . '</recurrence>' . K_NEWLINE;
            $xml .= K_TAB . K_TAB . K_TAB . '<recurrence_percent>' . F_formatXMLPercentage($mr['recurrence'] / $num_questions) . '</recurrence_percent>' . K_NEWLINE;
            $xml .= K_TAB . K_TAB . K_TAB . '<points>' . number_format($mr['average_score'], 3, '.', '') . '</points>' . K_NEWLINE;
            $xml .= K_TAB . K_TAB . K_TAB . '<points_percent>' . F_formatXMLPercentage($mr['average_score'] / $question_max_score) . '</points_percent>' . K_NEWLINE;
            if (stripos($mr['average_time'], ':') !== FALSE) {
                // PostgreSQL returns formatted time, while MySQL returns the number of seconds
                $mr['average_time'] = strtotime($mr['average_time']);
            }
            $xml .= K_TAB . K_TAB . K_TAB . '<time>' . date('i:s', $mr['average_time']) . '</time>' . K_NEWLINE;
            $xml .= K_TAB . K_TAB . K_TAB . '<correct>' . $qsttestdata['right'] . '</correct>' . K_NEWLINE;
            $xml .= K_TAB . K_TAB . K_TAB . '<correct_percent>' . F_formatXMLPercentage($qsttestdata['right'] / $qsttestdata['num']) . '</correct_percent>' . K_NEWLINE;
            $xml .= K_TAB . K_TAB . K_TAB . '<wrong>' . $qsttestdata['wrong'] . '</wrong>' . K_NEWLINE;
            $xml .= K_TAB . K_TAB . K_TAB . '<wrong_percent>' . F_formatXMLPercentage($qsttestdata['wrong'] / $qsttestdata['num']) . '</wrong_percent>' . K_NEWLINE;
            $xml .= K_TAB . K_TAB . K_TAB . '<unanswered>' . $qsttestdata['unanswered'] . '</unanswered>' . K_NEWLINE;
            $xml .= K_TAB . K_TAB . K_TAB . '<unanswered_percent>' . F_formatXMLPercentage($qsttestdata['unanswered'] / $qsttestdata['num']) . '</unanswered_percent>' . K_NEWLINE;
            $xml .= K_TAB . K_TAB . K_TAB . '<undisplayed>' . $qsttestdata['undisplayed'] . '</undisplayed>' . K_NEWLINE;
            $xml .= K_TAB . K_TAB . K_TAB . '<undisplayed_percent>' . F_formatXMLPercentage($qsttestdata['undisplayed'] / $qsttestdata['num']) . '</undisplayed_percent>' . K_NEWLINE;
            $xml .= K_TAB . K_TAB . K_TAB . '<unrated>' . $qsttestdata['unrated'] . '</unrated>' . K_NEWLINE;
            $xml .= K_TAB . K_TAB . K_TAB . '<unrated_percent>' . F_formatXMLPercentage($qsttestdata['unrated'] / $qsttestdata['num']) . '</unrated_percent>' . K_NEWLINE;
            // answers statistics
            $sqla = 'SELECT *
				FROM ' . K_TABLE_ANSWERS . '
				WHERE answer_question_id=' . $mr['question_id'] . '
				ORDER BY answer_id';
            if ($ra = F_db_query($sqla, $db)) {
                while ($ma = F_db_fetch_array($ra)) {
                    $xml .= K_TAB . K_TAB . K_TAB . '<answer>' . K_NEWLINE;
                    $xml .= K_TAB . K_TAB . K_TAB . K_TAB . '<id>' . $ma['answer_id'] . '</id>' . K_NEWLINE;
                    $xml .= K_TAB . K_TAB . K_TAB . K_TAB . '<description>' . F_text_to_xml($ma['answer_description']) . '</description>' . K_NEWLINE;
                    $num_all_answers = F_count_rows(K_TABLE_TEST_USER . ', ' . K_TABLE_TESTS_LOGS . ', ' . K_TABLE_ANSWERS . ', ' . K_TABLE_LOG_ANSWER . ' WHERE logansw_answer_id=answer_id AND logansw_testlog_id=testlog_id AND testlog_testuser_id=testuser_id AND testuser_test_id=' . $test_id . ' AND testlog_question_id=' . $mr['question_id'] . '');
                    $num_answers = F_count_rows(K_TABLE_TEST_USER . ', ' . K_TABLE_TESTS_LOGS . ', ' . K_TABLE_ANSWERS . ', ' . K_TABLE_LOG_ANSWER . ' WHERE answer_id=' . $ma['answer_id'] . ' AND logansw_answer_id=answer_id AND logansw_testlog_id=testlog_id AND testlog_testuser_id=testuser_id AND testuser_test_id=' . $test_id . ' AND testlog_question_id=' . $mr['question_id'] . '');
                    $right_answers = F_count_rows(K_TABLE_TEST_USER . ', ' . K_TABLE_TESTS_LOGS . ', ' . K_TABLE_ANSWERS . ', ' . K_TABLE_LOG_ANSWER . ' WHERE answer_id=' . $ma['answer_id'] . ' AND logansw_answer_id=answer_id AND logansw_testlog_id=testlog_id AND testlog_testuser_id=testuser_id AND testuser_test_id=' . $test_id . ' AND testlog_question_id=' . $mr['question_id'] . ' AND ((answer_isright=\'0\' AND logansw_selected=0) OR (answer_isright=\'1\' AND logansw_selected=1) OR (answer_position IS NOT NULL AND logansw_position IS NOT NULL AND answer_position=logansw_position))');
                    $wrong_answers = F_count_rows(K_TABLE_TEST_USER . ', ' . K_TABLE_TESTS_LOGS . ', ' . K_TABLE_ANSWERS . ', ' . K_TABLE_LOG_ANSWER . ' WHERE answer_id=' . $ma['answer_id'] . ' AND logansw_answer_id=answer_id AND logansw_testlog_id=testlog_id AND testlog_testuser_id=testuser_id AND testuser_test_id=' . $test_id . ' AND testlog_question_id=' . $mr['question_id'] . ' AND ((answer_isright=\'0\' AND logansw_selected=1) OR (answer_isright=\'1\' AND logansw_selected=0) OR (answer_position IS NOT NULL AND answer_position!=logansw_position))');
                    $unanswered = F_count_rows(K_TABLE_TEST_USER . ', ' . K_TABLE_TESTS_LOGS . ', ' . K_TABLE_ANSWERS . ', ' . K_TABLE_LOG_ANSWER . ' WHERE answer_id=' . $ma['answer_id'] . ' AND logansw_answer_id=answer_id AND logansw_testlog_id=testlog_id AND testlog_testuser_id=testuser_id AND testuser_test_id=' . $test_id . ' AND testlog_question_id=' . $mr['question_id'] . ' AND logansw_selected=-1');
                    $xml .= K_TAB . K_TAB . K_TAB . K_TAB . '<recurrence>' . $num_answers . '</recurrence>' . K_NEWLINE;
                    $perc = 0;
                    if ($num_all_answers > 0) {
                        $perc = $num_answers / $num_all_answers;
                    }
                    $xml .= K_TAB . K_TAB . K_TAB . K_TAB . '<recurrence_percent>' . F_formatXMLPercentage($perc) . '</recurrence_percent>' . K_NEWLINE;
                    $xml .= K_TAB . K_TAB . K_TAB . K_TAB . '<correct>' . $right_answers . '</correct>' . K_NEWLINE;
                    $perc = 0;
                    if ($num_answers > 0) {
                        $perc = $right_answers / $num_answers;
                    }
                    $xml .= K_TAB . K_TAB . K_TAB . K_TAB . '<correct_percent>' . F_formatXMLPercentage($perc) . '</correct_percent>' . K_NEWLINE;
                    $xml .= K_TAB . K_TAB . K_TAB . K_TAB . '<wrong>' . $wrong_answers . '</wrong>' . K_NEWLINE;
                    $perc = 0;
                    if ($num_answers > 0) {
                        $perc = round($wrong_answers / $num_answers);
                    }
                    $xml .= K_TAB . K_TAB . K_TAB . K_TAB . '<wrong_percent>' . F_formatXMLPercentage($perc) . '</wrong_percent>' . K_NEWLINE;
                    $xml .= K_TAB . K_TAB . K_TAB . K_TAB . '<unanswered>' . $unanswered . '</unanswered>' . K_NEWLINE;
                    $perc = 0;
                    if ($num_answers > 0) {
                        $perc = round($unanswered / $num_answers);
                    }
                    $xml .= K_TAB . K_TAB . K_TAB . K_TAB . '<unanswered_percent>' . F_formatXMLPercentage($perc) . '</unanswered_percent>' . K_NEWLINE;
                    $xml .= K_TAB . K_TAB . K_TAB . '</answer>' . K_NEWLINE;
                }
            } else {
                F_display_db_error();
            }
            $xml .= K_TAB . K_TAB . '</question>' . K_NEWLINE;
        }
    } else {
        F_display_db_error();
    }
    $xml .= K_TAB . '</body>' . K_NEWLINE;
    $xml .= '</tcexamquestionstats>' . K_NEWLINE;
    return $xml;
}
/**
 * Display user selection XHTML table (popup mode).
 * @author Nicola Asuni
 * @since 2012-04-14
 * @param $order_field (string) Order by column name.
 * @param $orderdir (int) Order direction.
 * @param $firstrow (int) Number of first row to display.
 * @param $rowsperpage (int) Number of rows per page.
 * @param $andwhere (string) Additional SQL WHERE query conditions.
 * @param $searchterms (string) Search terms.
 * @param string $cid ID of the calling form field.
 * @return false in case of empty database, true otherwise
 */
function F_show_select_test_popup($order_field, $orderdir, $firstrow, $rowsperpage, $andwhere = '', $searchterms = '', $cid = 0)
{
    global $l, $db;
    require_once '../config/tce_config.php';
    require_once '../../shared/code/tce_functions_page.php';
    require_once '../../shared/code/tce_functions_form.php';
    $filter = 'cid=' . $cid;
    if ($l['a_meta_dir'] == 'rtl') {
        $txtalign = 'right';
        $numalign = 'left';
    } else {
        $txtalign = 'left';
        $numalign = 'right';
    }
    $order_field = F_escape_sql($db, $order_field);
    $orderdir = intval($orderdir);
    $firstrow = intval($firstrow);
    $rowsperpage = intval($rowsperpage);
    if (empty($order_field) or !in_array($order_field, array('test_name', 'test_description', 'test_begin_time', 'test_end_time', 'test_duration_time', 'test_ip_range', 'test_results_to_users', 'test_report_to_users', 'test_score_right', 'test_score_wrong', 'test_score_unanswered', 'test_max_score', 'test_user_id', 'test_score_threshold', 'test_random_questions_select', 'test_random_questions_order', 'test_questions_order_mode', 'test_random_answers_select', 'test_random_answers_order', 'test_answers_order_mode', 'test_comment_enabled', 'test_menu_enabled', 'test_noanswer_enabled', 'test_mcma_radio', 'test_repeatable', 'test_mcma_partial_score', 'test_logout_on_timeout'))) {
        $order_field = 'test_begin_time DESC,test_name';
    }
    if ($orderdir == 0) {
        $nextorderdir = 1;
        $full_order_field = $order_field;
    } else {
        $nextorderdir = 0;
        $full_order_field = $order_field . ' DESC';
    }
    if (!F_count_rows(K_TABLE_TESTS)) {
        // if the table is void (no items) display message
        F_print_error('MESSAGE', $l['m_databasempty']);
        return FALSE;
    }
    $wherequery = '';
    if (empty($wherequery)) {
        $wherequery = ' WHERE';
    } else {
        $wherequery .= ' AND';
    }
    $wherequery .= ' (test_id>0)';
    if ($_SESSION['session_user_level'] < K_AUTH_ADMINISTRATOR) {
        $wherequery .= ' AND test_user_id IN (' . F_getAuthorizedUsers($_SESSION['session_user_id']) . ')';
    }
    if (!empty($andwhere)) {
        $wherequery .= ' AND (' . $andwhere . ')';
    }
    $sql = 'SELECT * FROM ' . K_TABLE_TESTS . $wherequery . ' ORDER BY ' . $full_order_field;
    if (K_DATABASE_TYPE == 'ORACLE') {
        $sql = 'SELECT * FROM (' . $sql . ') WHERE rownum BETWEEN ' . $firstrow . ' AND ' . ($firstrow + $rowsperpage) . '';
    } else {
        $sql .= ' LIMIT ' . $rowsperpage . ' OFFSET ' . $firstrow . '';
    }
    if ($r = F_db_query($sql, $db)) {
        if ($m = F_db_fetch_array($r)) {
            // -- Table structure with links:
            echo '<div class="container">';
            echo '<table class="userselect" style="font-size:80%;">' . K_NEWLINE;
            // table header
            echo '<tr>' . K_NEWLINE;
            if (strlen($searchterms) > 0) {
                $filter .= '&amp;searchterms=' . urlencode($searchterms);
            }
            echo F_select_table_header_element('test_begin_time', $nextorderdir, $l['w_time_begin'] . ' ' . $l['w_datetime_format'], $l['w_time_begin'], $order_field, $filter);
            echo F_select_table_header_element('test_end_time', $nextorderdir, $l['w_time_end'] . ' ' . $l['w_datetime_format'], $l['w_time_end'], $order_field, $filter);
            echo F_select_table_header_element('test_name', $nextorderdir, $l['h_test_name'], $l['w_name'], $order_field, $filter);
            echo F_select_table_header_element('test_description', $nextorderdir, $l['h_test_description'], $l['w_description'], $order_field, $filter);
            echo '</tr>' . K_NEWLINE;
            $itemcount = 0;
            do {
                $itemcount++;
                // on click the user ID will be returned on the calling form field
                $jsaction = 'javascript:window.opener.document.getElementById(\'' . $cid . '\').value=' . $m['test_id'] . ';';
                $jsaction .= 'window.opener.document.getElementById(\'' . $cid . '\').onchange();';
                $jsaction .= 'window.close();';
                echo '<tr>' . K_NEWLINE;
                echo '<td style="text-align:' . $txtalign . ';">&nbsp;' . htmlspecialchars($m['test_begin_time'], ENT_NOQUOTES, $l['a_meta_charset']) . '</td>' . K_NEWLINE;
                echo '<td style="text-align:' . $txtalign . ';">&nbsp;' . htmlspecialchars($m['test_end_time'], ENT_NOQUOTES, $l['a_meta_charset']) . '</td>' . K_NEWLINE;
                echo '<td style="text-align:' . $txtalign . ';">&nbsp;<a href="#" onclick="' . $jsaction . '" title="[' . $l['w_select'] . ']">' . htmlspecialchars($m['test_name'], ENT_NOQUOTES, $l['a_meta_charset']) . '</a></td>' . K_NEWLINE;
                echo '<td style="text-align:' . $txtalign . ';">&nbsp;' . htmlspecialchars($m['test_description'], ENT_NOQUOTES, $l['a_meta_charset']) . '</td>' . K_NEWLINE;
                echo '</tr>' . K_NEWLINE;
            } while ($m = F_db_fetch_array($r));
            echo '</table>' . K_NEWLINE;
            echo '<input type="hidden" name="order_field" id="order_field" value="' . $order_field . '" />' . K_NEWLINE;
            echo '<input type="hidden" name="orderdir" id="orderdir" value="' . $orderdir . '" />' . K_NEWLINE;
            echo '<input type="hidden" name="firstrow" id="firstrow" value="' . $firstrow . '" />' . K_NEWLINE;
            echo '<input type="hidden" name="rowsperpage" id="rowsperpage" value="' . $rowsperpage . '" />' . K_NEWLINE;
            echo '<div class="row"><hr /></div>' . K_NEWLINE;
            // ---------------------------------------------------------------
            // -- page jumper (menu for successive pages)
            if ($rowsperpage > 0) {
                $sql = 'SELECT count(*) AS total FROM ' . K_TABLE_TESTS . '' . $wherequery . '';
                if (!empty($order_field)) {
                    $param_array = '&amp;order_field=' . urlencode($order_field) . '';
                }
                if (!empty($orderdir)) {
                    $param_array .= '&amp;orderdir=' . $orderdir . '';
                }
                if (!empty($searchterms)) {
                    $param_array .= '&amp;searchterms=' . urlencode($searchterms) . '';
                }
                $param_array .= '&amp;submitted=1';
                F_show_page_navigator($_SERVER['SCRIPT_NAME'], $sql, $firstrow, $rowsperpage, $param_array);
            }
            echo '</div>' . K_NEWLINE;
        } else {
            F_print_error('MESSAGE', $l['m_search_void']);
        }
    } else {
        F_display_db_error();
    }
    return TRUE;
}
/**
 * Display online users.
 * @author Nicola Asuni
 * @since 2001-10-18
 * @param $wherequery (string) users selection query
 * @param $order_field (string) order by column name
 * @param $orderdir (int) oreder direction
 * @param $firstrow (int) number of first row to display
 * @param $rowsperpage (int) number of rows per page
 * @return false in case of empty database, true otherwise
 */
function F_list_online_users($wherequery, $order_field, $orderdir, $firstrow, $rowsperpage)
{
    global $l, $db;
    require_once '../config/tce_config.php';
    require_once '../../shared/code/tce_functions_page.php';
    require_once 'tce_functions_user_select.php';
    //initialize variables
    $orderdir = intval($orderdir);
    $firstrow = intval($firstrow);
    $rowsperpage = intval($rowsperpage);
    // order fields for SQL query
    if (empty($order_field) or !in_array($order_field, array('cpsession_id', 'cpsession_data'))) {
        $order_field = 'cpsession_expiry';
    }
    if ($orderdir == 0) {
        $nextorderdir = 1;
        $full_order_field = $order_field;
    } else {
        $nextorderdir = 0;
        $full_order_field = $order_field . ' DESC';
    }
    if (!F_count_rows(K_TABLE_SESSIONS)) {
        //if the table is void (no items) display message
        echo '<h2>' . $l['m_databasempty'] . '</h2>';
        return FALSE;
    }
    if (empty($wherequery)) {
        $sql = 'SELECT * FROM ' . K_TABLE_SESSIONS . ' ORDER BY ' . $full_order_field . '';
    } else {
        $wherequery = F_escape_sql($db, $wherequery);
        $sql = 'SELECT * FROM ' . K_TABLE_SESSIONS . ' ' . $wherequery . ' ORDER BY ' . $full_order_field . '';
    }
    if (K_DATABASE_TYPE == 'ORACLE') {
        $sql = 'SELECT * FROM (' . $sql . ') WHERE rownum BETWEEN ' . $firstrow . ' AND ' . ($firstrow + $rowsperpage) . '';
    } else {
        $sql .= ' LIMIT ' . $rowsperpage . ' OFFSET ' . $firstrow . '';
    }
    echo '<div class="container">' . K_NEWLINE;
    echo '<table class="userselect">' . K_NEWLINE;
    echo '<tr>' . K_NEWLINE;
    echo '<th>' . $l['w_user'] . '</th>' . K_NEWLINE;
    echo '<th>' . $l['w_level'] . '</th>' . K_NEWLINE;
    echo '<th>' . $l['w_ip'] . '</th>' . K_NEWLINE;
    echo '</tr>' . K_NEWLINE;
    if ($r = F_db_query($sql, $db)) {
        while ($m = F_db_fetch_array($r)) {
            $this_session = F_session_string_to_array($m['cpsession_data']);
            echo '<tr>';
            echo '<td align="left">';
            $user_str = '';
            if ($this_session['session_user_lastname']) {
                $user_str .= urldecode($this_session['session_user_lastname']) . ', ';
            }
            if ($this_session['session_user_firstname']) {
                $user_str .= urldecode($this_session['session_user_firstname']) . '';
            }
            $user_str .= ' (' . urldecode($this_session['session_user_name']) . ')';
            if (F_isAuthorizedEditorForUser($this_session['session_user_id'])) {
                echo '<a href="tce_edit_user.php?user_id=' . $this_session['session_user_id'] . '">' . $user_str . '</a>';
            } else {
                echo $user_str;
            }
            echo '</td>';
            echo '<td>' . $this_session['session_user_level'] . '</td>';
            echo '<td>' . $this_session['session_user_ip'] . '</td>';
            echo '</tr>' . K_NEWLINE;
        }
    } else {
        F_display_db_error();
    }
    echo '</table>' . K_NEWLINE;
    // --- ------------------------------------------------------
    // --- page jump
    if ($rowsperpage > 0) {
        $sql = 'SELECT count(*) AS total FROM ' . K_TABLE_SESSIONS . ' ' . $wherequery . '';
        if (!empty($order_field)) {
            $param_array = '&amp;order_field=' . urlencode($order_field) . '';
        }
        if (!empty($orderdir)) {
            $param_array .= '&amp;orderdir=' . $orderdir . '';
        }
        $param_array .= '&amp;submitted=1';
        F_show_page_navigator($_SERVER['SCRIPT_NAME'], $sql, $firstrow, $rowsperpage, $param_array);
    }
    echo '<div class="pagehelp">' . $l['hp_online_users'] . '</div>' . K_NEWLINE;
    echo '</div>' . K_NEWLINE;
    return TRUE;
}
Example #16
0
if (K_MAX_TESTS_MONTH !== false) {
    // month limit (last 30 days)
    $startdate = date(K_TIMESTAMP_FORMAT, $now - K_SECONDS_IN_MONTH);
    $numtests = F_count_rows(K_TABLE_TESTUSER_STAT, 'WHERE tus_date>=\'' . $startdate . '\' AND tus_date<=\'' . $enddate . '\'');
    $limits .= '<tr';
    if (K_MAX_TESTS_MONTH - $numtests <= 0) {
        $limits .= ' style="text-align:right;background-color:#FFCCCC;" title="' . $l['w_over_limit'] . '"';
    } else {
        $limits .= ' style="text-align:right;background-color:#CCFFCC;" title="' . $l['w_under_limit'] . '"';
    }
    $limits .= '><td style="text-align:left;">' . $l['w_month'] . '</td><td>' . K_MAX_TESTS_MONTH . '</td><td>' . $numtests . '</td><td><strong>' . (K_MAX_TESTS_MONTH - $numtests) . '</strong></td></tr>';
}
if (K_MAX_TESTS_YEAR !== false) {
    // year limit (last 365 days)
    $startdate = date(K_TIMESTAMP_FORMAT, $now - K_SECONDS_IN_YEAR);
    $numtests = F_count_rows(K_TABLE_TESTUSER_STAT, 'WHERE tus_date>=\'' . $startdate . '\' AND tus_date<=\'' . $enddate . '\'');
    $limits .= '<tr';
    if (K_MAX_TESTS_YEAR - $numtests <= 0) {
        $limits .= ' style="text-align:right;background-color:#FFCCCC;" title="' . $l['w_over_limit'] . '"';
    } else {
        $limits .= ' style="text-align:right;background-color:#CCFFCC;" title="' . $l['w_under_limit'] . '"';
    }
    $limits .= '><td style="text-align:left;">' . $l['w_year'] . '</td><td>' . K_MAX_TESTS_YEAR . '</td><td>' . $numtests . '</td><td><strong>' . (K_MAX_TESTS_YEAR - $numtests) . '</strong></td></tr>';
}
if (strlen($limits) > 0) {
    echo '<table style="border: 1px solid #808080;margin-left:auto; margin-right:auto;"><tr><th colspan="4" style="text-align:center;">' . $l['w_remaining_tests'] . '</th></tr><tr style="background-color:#CCCCCC;"><th>' . $l['w_limit'] . '</th><th>' . $l['w_max'] . '</th><th>' . $l['w_executed'] . '</th><th>' . $l['w_remaining'] . '</th></tr>' . $limits . '</table><br />' . K_NEWLINE;
}
echo $l['d_admin_index'];
require_once 'tce_page_footer.php';
//============================================================+
// END OF FILE
/**
 * Returns true if the current user is authorized to update and delete the selected database record.
 * @author Nicola Asuni
 * @since 2006-03-11
 * @param $table (string) table to be modified
 * @param $field_id_name (string) name of the main ID field of the table
 * @param $value_id (int) value of the ID field of the table
 * @param $field_user_id (string) name of the foreign key to to user_id
 * @return boolean true if the user is authorized, false otherwise
 */
function F_isAuthorizedUser($table, $field_id_name, $value_id, $field_user_id)
{
    global $l, $db;
    require_once '../config/tce_config.php';
    $table = F_escape_sql($table);
    $field_id_name = F_escape_sql($field_id_name);
    $value_id = intval($value_id);
    $field_user_id = F_escape_sql($field_user_id);
    $user_id = intval($_SESSION['session_user_id']);
    // check for administrator
    if ($_SESSION['session_user_level'] >= K_AUTH_ADMINISTRATOR) {
        return true;
    }
    // check for original author
    if (F_count_rows($table . ' WHERE ' . $field_id_name . '=' . $value_id . ' AND ' . $field_user_id . '=' . $user_id . ' LIMIT 1') > 0) {
        return true;
    }
    // check for author's groups
    // get author ID
    $author_id = 0;
    $sql = 'SELECT ' . $field_user_id . ' FROM ' . $table . ' WHERE ' . $field_id_name . '=' . $value_id . ' LIMIT 1';
    if ($r = F_db_query($sql, $db)) {
        if ($m = F_db_fetch_array($r)) {
            $author_id = $m[0];
        }
    } else {
        F_display_db_error();
    }
    if ($author_id > 1 and F_count_rows(K_TABLE_USERGROUP . ' AS ta, ' . K_TABLE_USERGROUP . ' AS tb
		WHERE ta.usrgrp_group_id=tb.usrgrp_group_id
			AND ta.usrgrp_user_id=' . $author_id . '
			AND tb.usrgrp_user_id=' . $user_id . '
			LIMIT 1') > 0) {
        return true;
    }
    return false;
}
/**
 * Get an object description in dot format for graphviz.
 * @param $obj_id (int) ID of parent object.
 * @param $obj_level (int) Nesting level.
 * @return string dot map.
 */
function F_get_object_dot_map($obj_id, $obj_level)
{
    global $l, $db;
    require_once '../config/tce_config.php';
    include '../../shared/code/htmlcolors.php';
    $dot = '';
    $spacer = str_repeat(K_TAB, $obj_level);
    $spacerb = $spacer . K_TAB;
    // get object data
    $sqlobj = 'SELECT * FROM ' . K_TABLE_OBJECTS . ', ' . K_TABLE_OBJECT_TYPES . ' WHERE obj_obt_id=obt_id AND obj_id=' . $obj_id . ' ORDER BY obj_name ASC';
    if ($robj = F_db_query($sqlobj, $db)) {
        $mobj = F_db_fetch_array($robj);
    } else {
        F_display_db_error();
    }
    $color = array_keys(TCPDF_COLORS::$webcolor, $mobj['obt_color']);
    if (!empty($color) and isset($color[0])) {
        $color = $color[0];
    } else {
        $color = 'white';
    }
    if (F_count_rows(K_TABLE_OBJECTS . ', ' . K_TABLE_OBJECTS_MAP, 'WHERE omp_child_obj_id=obj_id AND omp_parent_obj_id=' . $obj_id) > 0) {
        // CLUSTER
        $dot .= $spacer . 'subgraph clusterOBJ' . $mobj['obj_id'] . ' {' . K_NEWLINE;
        $dot .= $spacerb . 'color=' . (getContrastColor(TCPDF_COLORS::$webcolor[$color]) == '000000' ? 'black' : 'white') . ';' . K_NEWLINE;
        $dot .= $spacerb . 'bgcolor=' . $color . ';' . K_NEWLINE;
        $dot .= $spacerb . 'label="' . F_compact_string($mobj['obj_name'], true) . '";' . K_NEWLINE;
        $dot .= $spacerb . 'URL="tce_view_object?obj_id=' . $mobj['obj_id'] . '";' . K_NEWLINE;
        $dot .= $spacerb . 'tooltip="' . F_compact_string($mobj['obj_description'] . ' - ' . $mobj['obj_label'] . ' - ' . $mobj['obj_tag'], true) . '";' . K_NEWLINE;
        $dot .= $spacerb . 'node [shape=circle,style=filled,color=black,fontname=Helvetica,fontsize=12,fontcolor=black];' . K_NEWLINE;
        // for each child
        $sql = 'SELECT obj_id, obj_name, obj_label, obj_tag FROM ' . K_TABLE_OBJECTS . ', ' . K_TABLE_OBJECTS_MAP . ' WHERE omp_child_obj_id=obj_id AND omp_parent_obj_id=' . $obj_id . ' ORDER BY obj_name ASC';
        if ($r = F_db_query($sql, $db)) {
            while ($m = F_db_fetch_array($r)) {
                $dot .= F_get_object_dot_map($m['obj_id'], $obj_level + 1);
            }
        } else {
            F_display_db_error();
        }
        $dot .= $spacer . '}' . K_NEWLINE;
    } else {
        // NODE
        $dot .= $spacer . 'OBJ' . $mobj['obj_id'] . ' [fillcolor=' . $color . ',label="' . F_compact_string($mobj['obj_name'], true) . '",URL="tce_edit_objects.php?obj_id=' . $mobj['obj_id'] . '",tooltip="' . F_compact_string($mobj['obj_description'] . ' - ' . $mobj['obj_label'] . ' - ' . $mobj['obj_tag'], true) . '"];' . K_NEWLINE;
    }
    return $dot;
}