/** * Makes SQL for the text labels for the course nodes. * * @static * @param block_ajax_marking_query $query */ protected function alter_query(block_ajax_marking_query $query) { // Same order as the super query will need them. Prefixed so we will have it as the // first column for the GROUP BY. $query->add_from(array('join' => 'INNER JOIN', 'table' => 'course_modules', 'on' => 'course_modules.id = countwrapperquery.id')); $query->add_select(array('table' => 'course_modules', 'column' => 'id', 'alias' => 'coursemoduleid')); // The javascript needs this for styling. $query->add_select(array('table' => 'countwrapperquery', 'column' => 'modulename')); // This will add the stuff that joins to the various module tables and gets the right names. $moduleclasses = block_ajax_marking_get_module_classes(); $introcoalesce = array(); $namecoalesce = array(); $orderbycoalesce = array(); foreach ($moduleclasses as $moduleclass) { $moduletablename = $moduleclass->get_module_name(); $query->add_from(array('join' => 'LEFT JOIN', 'table' => $moduletablename, 'on' => "(course_modules.instance = " . $moduletablename . ".id\n AND course_modules.module = '" . $moduleclass->get_module_id() . "')")); $namecoalesce[$moduletablename] = 'name'; $introcoalesce[$moduletablename] = 'intro'; $orderbycoalesce[$moduletablename] = $moduletablename . '.name'; } $query->add_select(array('table' => 'course_modules', 'column' => 'id', 'alias' => 'coursemoduleid')); $query->add_select(array('table' => $namecoalesce, 'function' => 'COALESCE', 'column' => 'name', 'alias' => 'name')); $query->add_select(array('table' => $introcoalesce, 'function' => 'COALESCE', 'column' => 'intro', 'alias' => 'tooltip')); $query->add_orderby('COALESCE(' . implode(', ', $orderbycoalesce) . ') ASC'); // This will add the stuff that will show us the name of the actual module instance. // We use the same stuff for both config and marking trees, but the config tree doesn't need // the stuff to pull through submission counts. // TODO separate counts. // This allows us to have separate decorators, but may obfuscate what's happening a bit. // Code is not duplicated, though. }
/** * Returns the sql and params array for 'IN (x, y, z)' where xyz are the ids of teacher or * non-editing teacher roles * * @return array $sql and $param */ function block_ajax_marking_teacherrole_sql() { global $DB; $mods = block_ajax_marking_get_module_classes(); $capabilities = array(); foreach ($mods as $mod) { $capabilities[] = $mod->get_capability(); } list($capsql, $capparams) = $DB->get_in_or_equal($capabilities); $sql = "\n SELECT DISTINCT(role.id)\n FROM {role} role\n INNER JOIN {role_capabilities} rc\n ON role.id = rc.roleid\n WHERE rc.contextid = 1\n AND " . $DB->sql_compare_text('rc.capability') . " " . $capsql; // TODO should be a site wide or block level setting. $teacherroles = $DB->get_records_sql($sql, $capparams); // This is in case we can't do get_in_or_equal() because no roles are found and we get false. if (!$teacherroles) { return array('', array()); } $teacherroleids = array_keys($teacherroles); return $DB->get_in_or_equal($teacherroleids); }
/** * If we have a coursemoduleid, we want to be able to get the module object that corresponds * to it * * @static * @param int $coursemoduleid * @return block_ajax_marking_module_base|bool */ private static function get_module_object_from_cmid($coursemoduleid) { global $DB; $moduleclasses = block_ajax_marking_get_module_classes(); $moduleid = $DB->get_field('course_modules', 'module', array('id' => $coursemoduleid)); foreach ($moduleclasses as $moduleclass) { /* @var $moduleclass block_ajax_marking_module_base */ if ($moduleclass->get_module_id() == $moduleid) { // We don't want this one as we're filtering by a single coursemodule. return $moduleclass; } } return false; }
// along with Moodle. If not, see <http://www.gnu.org/licenses/>. /** * Saves data sent back via AJAX from the block config or grading interfaces * * @package block * @subpackage ajax_marking * @copyright 2011 Matt Gibson * @author Matt Gibson {@link http://moodle.org/user/view.php?id=81450} * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ if (!defined('AJAX_SCRIPT')) { define('AJAX_SCRIPT', true); } require_once dirname(__FILE__) . '/../../../config.php'; global $CFG; require_once $CFG->dirroot . '/blocks/ajax_marking/lib.php'; block_ajax_marking_login_error(); require_login(0, false); // Target = what function is going to be doing the save operation. Either a core thing for // config stuff, or a module name. $target = required_param('target', PARAM_ALPHA); // Work out where to send it for processing. switch ($target) { case 'config_save': break; default: $modules = block_ajax_marking_get_module_classes(); $modules[$target]->ajax_save(); break; } // Send it.
/** * * We need a rendered icon for each node type. We can't rely on CSS to do this * as there is no mechanism for generating it dynamically, i.e. having an arbitrary * number of CSS rules generated, one for each module plugin. These icons are * transplanted using JS to the nodes as needed. * * @return string HTML */ private function get_dynamic_icons_html() { global $OUTPUT; $modclasses = block_ajax_marking_get_module_classes(); $html = ''; foreach (array_keys($modclasses) as $modname) { $html .= '<img id="block_ajax_marking_' . $modname . '_icon" class="dynamicicon" src="' . $OUTPUT->pix_url('icon', $modname) . '" alt="' . $modname . '" title="' . $modname . '" />'; } $html .= '<img id="block_ajax_marking_course_icon" class="dynamicicon" src="' . $OUTPUT->pix_url('c/course') . '" alt="' . get_string('course') . '" title="' . get_string('course') . '" />'; $html .= '<img id="block_ajax_marking_group_icon" class="dynamicicon" src="' . $OUTPUT->pix_url('c/group') . '" alt="' . get_string('group') . '" title="' . get_string('group') . '" />'; $html .= '<img id="block_ajax_marking_cohort_icon" class="dynamicicon" src="' . $OUTPUT->pix_url('c/group') . '" alt="' . get_string('cohort', 'cohort') . '" title="' . get_string('cohort', 'cohort') . '" />'; $html .= '<img id="block_ajax_marking_hide_icon" class="dynamicicon" src="' . $OUTPUT->pix_url('t/hide') . '" alt="' . get_string('hide') . '" title="' . get_string('hide') . '" />'; $html .= '<img id="block_ajax_marking_show_icon" class="dynamicicon" src="' . $OUTPUT->pix_url('t/show') . '" alt="' . get_string('show') . '" title="' . get_string('show') . '" />'; $html .= '<img id="block_ajax_marking_showgroups_icon" class="dynamicicon" src="' . $OUTPUT->pix_url('group-disabled', 'block_ajax_marking') . '" alt="' . get_string('showgroups', 'block_ajax_marking') . '" title="' . get_string('showgroups', 'block_ajax_marking') . '" />'; $html .= '<img id="block_ajax_marking_hidegroups_icon" class="dynamicicon" src="' . $OUTPUT->pix_url('group', 'block_ajax_marking') . '" alt="' . get_string('hidegroups', 'block_ajax_marking') . '" title="' . get_string('hidegroups', 'block_ajax_marking') . '" />'; return $html; }
/** * For each module, we need to see if we can actually get any data back using the query from * the module's query factory. Possible problem with third (fourth?) party module access code, * so check first to see if the generator can handle making one to test with. */ public function test_module_query_factories() { global $DB; // Assignment module is disabled in the PHPUnit DB, so we need to re-enable it. $DB->set_field('modules', 'visible', 1, array('name' => 'assignment')); $classes = block_ajax_marking_get_module_classes(); foreach ($classes as $modclass) { $modname = $modclass->get_module_name(); // We need some submissions, but these are different for every module. // Without a standardised way of doing this, we will use methods in this class to do // the job until a better way emerges. $createdatamethod = 'create_' . $modname . '_submission_data'; if (method_exists($this, $createdatamethod)) { // Let the modules decide what number of things should be expected. Some are more // complex than others. $expectedcount = $this->{$createdatamethod}(); if (empty($expectedcount)) { continue; } } else { // No point carrying on without some data to check. continue; } // Make query. $query = $modclass->query_factory(); // We will get an error if we leave it like this as the userids in the first // column are not unique. $wrapper = new block_ajax_marking_query_base(); $wrapper->add_select(array('function' => 'COUNT', 'column' => '*', 'alias' => 'count')); $wrapper->add_from(array('table' => $query, 'alias' => 'modulequery')); // Run query. Get one stdClass with a count property. $unmarkedstuff = $wrapper->execute(); // Make sure we get the right number of things back. $this->assertEquals($expectedcount, reset($unmarkedstuff)->count); // Now make sure we have the right columns for the SQL UNION ALL. // We will get duplicate user ids causing problems in the first column if we // use standard DB functions. $records = $query->execute(true); $firstrow = $records->current(); } }