qcollection.module in Quiz 6.6
The main file for qcollection.
A question item collection organizes quiz questions to make them easier to find and to collect together for one's personal use.
An item collection can be turned into a quiz for taking by a student.
File
includes/qcollection/qcollection.moduleView source
<?php
/**
* The main file for qcollection.
*
* A question item collection organizes quiz questions to make them easier to find
* and to collect together for one's personal use.
*
* An item collection can be turned into a quiz for taking by a student.
*
* @file
*/
define('QCOLLECTION_NAME', 'Question item collection');
/**
* Implementation of hook_help().
*/
function qcollection_help($path, $args) {
if ($path == 'admin/help#qcollection') {
return t('This module provides a question item collection type for Quiz.');
}
}
/**
* Implementation of hook_perm().
*/
function qcollection_perm() {
return array(
// Managing qcollections:
'access qcollection',
'create qcollection',
'edit own qcollection',
'edit any qcollection',
'delete any qcollection',
'delete own qcollection',
);
}
/**
* Implementation of hook_access().
*/
function qcollection_access($op, $node, $account) {
// Admin can do all of this.
if (user_access('administer quiz', $account)) {
return TRUE;
}
if (!user_access('access qcollection')) {
// If you can't access, you get NOTHING!
// Otherwise, we allow further permission checking.
return FALSE;
}
switch ($op) {
case 'create':
return user_access('create qcollection', $account);
case 'update':
return user_access('edit any qcollection', $account) || user_access('edit own qcollection', $account) && $account->uid == $node->uid;
case 'delete':
return user_access('delete any qcollection', $account) || user_access('delete own qcollection', $account) && $account->uid == $node->uid;
}
}
/**
* Implementation of hook_node_info().
*/
function qcollection_node_info() {
return array(
'qcollection' => array(
'name' => t(QCOLLECTION_NAME),
'module' => 'qcollection',
'description' => t('A content type for the quiz module: gathers question items into a collection, separate from quiz-taking.'),
'has_title' => TRUE,
'has_body' => TRUE,
'body_label' => t('Notes'),
),
);
}
/**
* Implementation of qcollection_menu().
*/
function qcollection_menu() {
// Menu item for managing items in a collection
$items['node/%qcollection_type_access/items'] = array(
'title' => t('Manage items'),
'page callback' => 'qcollection_items',
'page arguments' => array(
1,
),
'access callback' => 'node_access',
'access arguments' => array(
'update',
1,
),
'type' => MENU_LOCAL_TASK,
'file' => 'qcollection.inc',
);
// Menu item to export item list into a new quiz
$items['node/%qcollection_type_access/export-quiz'] = array(
'title' => t('Export as quiz'),
'page callback' => 'qcollection_export_quiz',
'page arguments' => array(
1,
),
'access callback' => 'user_access',
'access arguments' => array(
'create quiz',
),
'type' => MENU_LOCAL_TASK,
'file' => 'qcollection.inc',
);
// Menu item to download item collection in a portable format
$items['node/%qcollection_type_access/download'] = array(
'title' => t('Download'),
'page callback' => 'qcollection_download',
'page arguments' => array(
1,
),
// FIXME: This needs to check to see if the user owns the qcollection.
'access callback' => 'node_access',
'access arguments' => array(
'update',
1,
),
'type' => MENU_LOCAL_TASK,
'file' => 'qcollection.inc',
);
return $items;
}
/**
* Implementation of hook_theme().
*/
function qcollection_theme() {
return array(
'qcollection_question_table' => array(
'arguments' => array(
'questions' => NULL,
'quiz_id' => NULL,
),
'file' => 'qcollection.pages.inc',
),
);
}
/**
* Load a qcollection node and validate it.
*
* @param $arg
* The Node ID
* @return
* A qcollection node object or FALSE if a load failed.
*/
function qcollection_type_access_load($arg) {
// Simple verification/load of the node.
// ddebug_backtrace();
return ($node = node_load($arg)) && $node->type == 'qcollection' ? $node : FALSE;
}
function _qcollection_get_info($node) {
$quiz_vid = db_result(db_query("SELECT vid FROM {node} WHERE nid = %d", $quiz_nid));
// Get count of child questions (ignoring question_status)
$sql = 'SELECT COUNT(child_nid)
FROM {quiz_node_relationship}
WHERE parent_vid = %d
AND parent_nid = %d';
$questions_count = db_result(db_query($sql, $node->vid, $node->nid));
return compact('questions_count');
}
/**
* Implemention of hook_view().
*
*/
function qcollection_view($node, $teaser = FALSE, $page = FALSE, $links = TRUE) {
$node = node_prepare($node, $teaser);
$collection_nid = $node->nid;
$info = _qcollection_get_info($node);
$node->content['info'] = array(
// TODO theme the info block
'#value' => "<em>{$info['questions_count']} questions</em><br/>",
'#weight' => 0,
);
if (!$teaser) {
$questions = _quiz_get_questions($node->nid, $node->vid);
$output = theme('qcollection_question_table', $questions, $collection_nid);
$node->content['questions'] = array(
'#value' => $output,
'#weight' => 1,
);
}
if (user_access('create quiz')) {
$node->content['export-quiz'] = array(
'#value' => l(t('Export as quiz'), 'node/' . $collection_nid . '/export-quiz'),
'#weight' => 2,
);
}
return $node;
}
/**
* Implementation of hook_form().
*
*/
function qcollection_form(&$node) {
$type = node_get_types('type', $node);
$form = array();
$form['title'] = array(
'#type' => 'textfield',
'#title' => check_plain($type->title_label),
'#default_value' => $node->title,
'#description' => t('The name of the @item_collection.', array(
'@item_collection' => QCOLLECTION_NAME,
)),
'#required' => TRUE,
);
$form['body_field']['body'] = array(
'#type' => 'textarea',
'#title' => check_plain($type->body_label),
'#default_value' => $node->body,
'#description' => t('Notes on the contents and origin of the @qcollection entails', array(
'@qcollection' => QCOLLECTION_NAME,
)),
'#required' => FALSE,
);
$form['body_field']['format'] = filter_form($node->format);
return $form;
}
/**
* Implementation of hook_form_alter().
*
* Override settings in some existing forms. For example, we remove the
* preview button on a qcollection.
*/
function qcollection_form_alter(&$form, $form_state, $form_id) {
if ($form_id == 'qcollection_node_form') {
// Remove preview buttons:
unset($form['buttons']['preview']);
unset($form['buttons']['preview_changes']);
// TODO make preview work
}
}
/**
* Implementation of hook_update().
*/
function qcollection_update($node) {
// QCollection node vid (revision) was updated.
if ($node->revision) {
// Create new qcollection-question relation entries in the quiz_node_relationship table.
quiz_update_quiz_question_relationship($node->old_vid, $node->vid, $node->nid);
}
}
/**
* Implementation of hook_delete().
*/
function qcollection_delete($node) {
db_query('DELETE FROM {quiz_node_relationship} WHERE parent_nid = %d', $node->nid);
}
/**
* Implementation of hook_action_info()
*
* @return array of action info
*/
function qcollection_action_info() {
return array(
'qcollection_add_question_action' => array(
'type' => 'node',
// FIXME restrict to quiz question nodes
'description' => t('Add to an item collection'),
'configurable' => TRUE,
'hooks' => array(
'any' => TRUE,
),
),
);
}
/**
* Return a form for selecting collections and quizzes to which a node should be copied
*/
function qcollection_add_question_action_form($context) {
global $user;
$form = array();
// user's collections
$sql = "SELECT nid, title\n FROM {node}\n WHERE (type in ('qcollection')) AND (uid = %d)";
$result = db_query($sql, $user->uid);
while ($row = db_fetch_array($result)) {
$options[$row['nid']] = $row['title'];
}
// checkboxes for the qcollections the user has permission to add to
$form['my_collections'] = array(
'#type' => 'checkboxes',
'#title' => t('My Collections'),
'#options' => $options,
'#description' => t('Collections to which you can add question items.'),
);
return $form;
}
function qcollection_add_question_action_validate($form, $form_state) {
// validation code here ...
// FIXME validate that the input nodes are all questions
}
function qcollection_add_question_action_submit($form, $form_state) {
return array(
'targets' => $form_state['values']['my_collections'],
);
}
/**
* Callback function to copy a question node to one or more collections
*/
function qcollection_add_question_action(&$node, $context) {
_qcollection_add_question_to_collection($node, $context['targets']);
}
/**
* Add a question node to a qcollection
*/
function _qcollection_add_question_to_collection($question, $collections) {
$weight = 0;
// Now we add the question node to each collection
// (Note that we are using a subselect to get the most recent vid of the qcollection.)
$sql = "INSERT INTO {quiz_node_relationship} (parent_nid, parent_vid, child_nid, child_vid, question_status, weight)\n VALUES (%d, (SELECT vid FROM {node} WHERE nid = %d), %d, %d, %d, %d)";
foreach (array_filter($collections) as $collection_nid) {
db_query($sql, $collection_nid, $collection_nid, $question->nid, $question->vid, QUESTION_ALWAYS, $weight);
}
}
Functions
Constants
Name | Description |
---|---|
QCOLLECTION_NAME | The main file for qcollection. |