You are here

opigno_quiz_app.install in Opigno Quiz App 7

Defines module install logic.

File

opigno_quiz_app.install
View source
<?php

/**
 * @file
 * Defines module install  logic.
 */

/**
 * Implements hook_install().
 */
function opigno_quiz_app_install() {

  // Add the quiz weight field.
  $field = field_info_field('quiz_weight');
  if (empty($field)) {
    field_create_field(array(
      'field_name' => 'quiz_weight',
      'type' => 'number_float',
    ));
  }

  // Add the quiz type field.
  $field = field_info_field('quiz_type');
  if (empty($field)) {
    field_create_field(array(
      'field_name' => 'quiz_type',
      'type' => 'list_text',
      'cardinality' => 1,
      'settings' => array(
        'allowed_values' => array(
          'quiz' => 'Quiz',
          'theory' => 'Theory',
          'mix' => 'Mix',
        ),
        'allowed_values_function' => '',
      ),
    ));
  }

  // Add the og required quiz field.
  $field = field_info_field('course_required_quiz_ref');
  if (empty($field)) {
    field_create_field(array(
      'cardinality' => FIELD_CARDINALITY_UNLIMITED,
      'field_name' => 'course_required_quiz_ref',
      'foreign keys' => array(
        'node' => array(
          'columns' => array(
            'target_id' => 'nid',
          ),
          'table' => 'node',
        ),
      ),
      'indexes' => array(
        'target_id' => array(
          0 => 'target_id',
        ),
      ),
      'module' => 'entityreference',
      'settings' => array(
        'handler' => 'views',
        'handler_settings' => array(
          'behaviors' => array(
            'views-select-list' => array(
              'status' => 0,
            ),
          ),
          'view' => array(
            'args' => array(),
            'display_name' => 'entityreference_1',
            'view_name' => 'opigno_quizzes',
          ),
        ),
        'target_type' => 'node',
      ),
      'type' => 'entityreference',
    ));
  }
  $instance = field_info_instance('node', 'quiz_weight', 'quiz');
  if (empty($instance)) {
    field_create_instance(array(
      'field_name' => 'quiz_weight',
      'entity_type' => 'node',
      'bundle' => 'quiz',
      'label' => "Quiz weight",
      'description' => "Sets the weight of this quiz for the final course assessment. Leave at 0 if this quiz should not be taken into account for the final grade.",
      'required' => TRUE,
      'default_value' => array(
        0 => array(
          'value' => 1,
        ),
      ),
    ));
  }
  $instance = field_info_instance('node', 'quiz_type', 'quiz');
  if (empty($instance)) {
    field_create_instance(array(
      'field_name' => 'quiz_type',
      'entity_type' => 'node',
      'bundle' => 'quiz',
      'label' => "Quiz type",
      'description' => "Sets the type of this lesson. Can be <em>theory</em> (containing theoretical slides), <em>quiz</em> (assessment, exam) and <em>mix</em> (containing both theoretical slides, SCORM packages, H5P rich contents, and assessments)",
      'required' => TRUE,
      'default_value' => array(
        0 => array(
          'value' => 1,
        ),
      ),
    ));
  }
  if (module_exists('opigno_calendar_app')) {
    opigno_quiz_app_enable_calendar_integration();
  }

  // Add the OG audience field.
  include_once drupal_get_path('module', 'og') . '/og_ui/og_ui.module';
  if (function_exists('og_ui_node_type_save')) {
    $types = array();
    if (function_exists('_quiz_question_get_implementations')) {
      $types += array_keys(_quiz_question_get_implementations());
    }
    array_unshift($types, "quiz");
    foreach ($types as $type) {
      variable_set('og_group_content_type_' . $type, TRUE);
      og_ui_node_type_save($type);
      variable_set('node_submitted_' . $type, 0);

      // Disable comments by default.
      if (module_exists('comment')) {
        variable_set('comment_' . $type, COMMENT_NODE_CLOSED);
      }

      // Make the body field be displayed fully on question.
      $instance = field_info_instance('node', 'body', $type);
      if (!empty($instance)) {
        if ($type == "cloze") {
          $instance['display']['question'] = array();
          $instance['display']['question']['label'] = "hidden";
          $instance['display']['question']['type'] = "hidden";
          $instance['display']['question']['weight'] = 0;
          $instance['display']['question']['settings'] = array();
        }
        else {
          $instance['display']['question']['type'] = 'text_default';
        }
        field_update_instance($instance);
      }
      $instance = field_info_instance('node', 'og_group_ref', $type);
      if (!empty($instance)) {
        foreach ($instance['display'] as $index => $display_mode) {
          $instance['display'][$index] = array();
          $instance['display'][$index]['label'] = "hidden";
          $instance['display'][$index]['type'] = "hidden";
          $instance['display'][$index]['weight'] = 3;
          $instance['display'][$index]['settings'] = array();
          field_update_instance($instance);
        }
      }
    }
  }

  //For scorm display the specific field
  $instance = field_info_instance('node', 'opigno_scorm_package', 'opigno_scorm_quiz_question');
  if (!empty($instance)) {
    $instance['display']['question'] = array();
    $instance['display']['question']['label'] = "hidden";
    $instance['display']['question']['type'] = "opigno_scorm_player";
    $instance['display']['question']['weight'] = 10;
    $instance['display']['question']['settings'] = array();
    $instance['display']['question']['module'] = "opigno_scorm_ui";
    field_update_instance($instance);
  }

  // Add the OG content access field.
  if (module_exists('og_access')) {
    og_create_field(OG_CONTENT_ACCESS_FIELD, 'node', 'quiz');
  }

  // If a OG course exists.
  if (defined('OPIGNO_COURSE_BUNDLE')) {
    $instance = field_info_instance('node', 'course_required_quiz_ref', OPIGNO_COURSE_BUNDLE);
    if (empty($instance)) {
      field_create_instance(array(
        'field_name' => 'course_required_quiz_ref',
        'entity_type' => 'node',
        'bundle' => OPIGNO_COURSE_BUNDLE,
        'label' => "Required quiz",
        'description' => "Defines a required quiz for this course. Users cannot finish the course without passing this quiz.",
        'required' => FALSE,
        'default_value' => 0,
      ));
    }
  }
}

/**
 * Implements hook_schema().
 */
function opigno_quiz_app_schema() {
  return array(
    'opigno_quiz_app_quiz_sort' => array(
      'fields' => array(
        'gid' => array(
          'type' => 'int',
          'unsigned' => TRUE,
          'not null' => TRUE,
        ),
        'quiz_nid' => array(
          'type' => 'int',
          'unsigned' => TRUE,
          'not null' => TRUE,
        ),
        'weight' => array(
          'type' => 'int',
          'not null' => TRUE,
          'default' => '0',
        ),
      ),
      'indexes' => array(
        'group_id' => array(
          'gid',
        ),
        'quiz_id' => array(
          'quiz_nid',
        ),
      ),
    ),
    'opigno_quiz_app_course_latest_viewed' => array(
      'fields' => array(
        'course_nid' => array(
          'type' => 'int',
          'unsigned' => TRUE,
          'not null' => TRUE,
        ),
        'quiz_nid' => array(
          'type' => 'int',
          'unsigned' => TRUE,
          'not null' => TRUE,
        ),
        'uid' => array(
          'type' => 'int',
          'not null' => TRUE,
          'unsigned' => TRUE,
        ),
        'result_id' => array(
          'type' => 'int',
          'not null' => TRUE,
          'unsigned' => TRUE,
        ),
      ),
      'primary key' => array(
        'course_nid',
        'uid',
      ),
    ),
  );
}

/**
 * Enable Calendar App integration.
 */
function opigno_quiz_app_enable_calendar_integration() {
  $field = field_info_field('field_add_to_calendar');
  if (empty($field)) {
    field_create_field(array(
      'translatable' => '0',
      'entity_types' => array(),
      'settings' => array(
        'allowed_values' => array(
          '0',
          '1',
        ),
        'allowed_values_function' => '',
      ),
      'storage' => array(
        'type' => 'field_sql_storage',
        'settings' => array(),
        'module' => 'field_sql_storage',
        'active' => '1',
        'details' => array(
          'sql' => array(
            'FIELD_LOAD_CURRENT' => array(
              'field_data_field_add_to_calendar' => array(
                'value' => 'field_add_to_calendar_value',
              ),
            ),
            'FIELD_LOAD_REVISION' => array(
              'field_revision_field_add_to_calendar' => array(
                'value' => 'field_add_to_calendar_value',
              ),
            ),
          ),
        ),
      ),
      'foreign keys' => array(),
      'indexes' => array(
        'value' => array(
          'value',
        ),
      ),
      'field_name' => 'field_add_to_calendar',
      'type' => 'list_boolean',
      'module' => 'list',
      'active' => '1',
      'locked' => '0',
      'cardinality' => '1',
      'deleted' => '0',
      'columns' => array(
        'value' => array(
          'type' => 'int',
          'not null' => FALSE,
        ),
      ),
      'bundles' => array(
        'node' => array(
          'quiz',
        ),
      ),
    ));
  }
  $instance = field_info_instance('node', 'field_add_to_calendar', 'quiz');
  if (empty($instance)) {
    field_create_instance(array(
      'label' => 'Add to calendar',
      'widget' => array(
        'weight' => '31',
        'type' => 'options_onoff',
        'module' => 'options',
        'active' => 1,
        'settings' => array(
          'display_label' => 1,
        ),
      ),
      'settings' => array(
        'user_register_form' => FALSE,
      ),
      'display' => array(
        'default' => array(
          'label' => 'above',
          'type' => 'hidden',
          'weight' => '3',
          'settings' => array(),
        ),
        'teaser' => array(
          'type' => 'hidden',
          'label' => 'above',
          'settings' => array(),
          'weight' => 0,
        ),
      ),
      'required' => 0,
      'description' => 'Add reminder to calendar',
      'default_value' => array(
        array(
          'value' => 0,
        ),
      ),
      'field_name' => 'field_add_to_calendar',
      'entity_type' => 'node',
      'bundle' => 'quiz',
      'deleted' => '0',
    ));
  }
  $instance = field_info_instance('node', 'opigno_calendar_date', 'quiz');
  if (empty($instance)) {
    field_create_instance(array(
      'label' => 'Calendar Date',
      'widget' => array(
        'weight' => '33',
        'type' => 'date_popup',
        'module' => 'date',
        'active' => 1,
        'settings' => array(
          'input_format' => 'm/d/Y - H:i:s',
          'input_format_custom' => '',
          'year_range' => '-3:+3',
          'increment' => '15',
          'label_position' => 'above',
          'text_parts' => array(),
        ),
      ),
      'settings' => array(
        'default_value' => 'now',
        'default_value_code' => '',
        'default_value2' => 'same',
        'default_value_code2' => '',
        'user_register_form' => FALSE,
      ),
      'display' => array(
        'default' => array(
          'label' => 'above',
          'type' => 'hidden',
          'weight' => '4',
          'settings' => array(),
        ),
        'teaser' => array(
          'type' => 'hidden',
          'label' => 'above',
          'settings' => array(),
          'weight' => 0,
        ),
      ),
      'required' => 0,
      'description' => '',
      'field_name' => 'opigno_calendar_date',
      'entity_type' => 'node',
      'bundle' => 'quiz',
      'deleted' => '0',
    ));
  }
  variable_set('node_submitted_quiz_drag_drop', 0);
}

/**
 * Enable h5p module
 */
function opigno_quiz_app_update_7101(&$sandbox) {
  if (!module_exists('h5p')) {
    module_enable(array(
      'h5p',
    ));
  }
  if (!module_exists('quiz_h5p')) {
    module_enable(array(
      'quiz_h5p',
    ));
  }
  if (module_exists("quiz")) {
    $instance = field_info_instance('node', 'quiz_type', 'quiz');
    if (!empty($instance)) {
      $instance['description'] = "Sets the type of this lesson. Can be <em>theory</em> (containing theoretical slides), <em>quiz</em> (assessment, exam) and <em>mix</em> (containing both theoretical slides, SCORM packages, H5P rich contents, and assessments)";
      field_update_instance($instance);
    }
    $types = array_keys(_quiz_question_get_implementations());
    foreach ($types as $type) {
      variable_set('node_submitted_' . $type, 0);

      // makes sure all question types are og group content
      if (module_exists("og_ui")) {
        include_once drupal_get_path('module', 'og') . '/og_ui/og_ui.module';
        $og_content_type = variable_get('og_group_content_type_' . $type, FALSE);
        if ($og_content_type == FALSE) {
          variable_set('og_group_content_type_' . $type, TRUE);
          og_ui_node_type_save($type);
        }
      }

      // makes all questions to have the body displaying for the question display mode
      $instance = field_info_instance('node', 'body', $type);
      if (!empty($instance)) {
        if ($type == "cloze") {
          $instance['display']['question'] = array();
          $instance['display']['question']['label'] = "hidden";
          $instance['display']['question']['type'] = "hidden";
          $instance['display']['question']['weight'] = 0;
          $instance['display']['question']['settings'] = array();
        }
        else {
          $instance['display']['question']['type'] = 'text_default';
        }
        field_update_instance($instance);
      }
      $instance = field_info_instance('node', 'og_group_ref', $type);
      if (!empty($instance)) {
        foreach ($instance['display'] as $index => $display_mode) {
          $instance['display'][$index] = array();
          $instance['display'][$index]['label'] = "hidden";
          $instance['display'][$index]['type'] = "hidden";
          $instance['display'][$index]['weight'] = 3;
          $instance['display'][$index]['settings'] = array();
          field_update_instance($instance);
        }
      }
    }

    //For scorm display the specific field
    $instance = field_info_instance('node', 'opigno_scorm_package', 'opigno_scorm_quiz_question');
    if (!empty($instance)) {
      $instance['display']['question'] = array();
      $instance['display']['question']['label'] = "hidden";
      $instance['display']['question']['type'] = "opigno_scorm_player";
      $instance['display']['question']['weight'] = 10;
      $instance['display']['question']['settings'] = array();
      $instance['display']['question']['module'] = "opigno_scorm_ui";
      field_update_instance($instance);
    }

    //For slide display pdf
    $instance = field_info_instance('node', 'slide_pdf', 'quiz_directions');
    if (!empty($instance)) {
      $instance['display']['question']['label'] = "hidden";
      $instance['display']['question']['module'] = "pdf";
      $instance['display']['question']['settings']['height'] = "600px";
      $instance['display']['question']['settings']['keep_pdfjs'] = 1;
      $instance['display']['question']['settings']['width'] = "100%";
      $instance['display']['question']['type'] = "pdf_default";
      $instance['display']['question']['weight'] = 10;
    }
  }

  /* Default permission */
  og_invalidate_cache();
  $roles = og_roles("node", "course", $gid = 0, $force_group = FALSE, $include_all = TRUE);
  foreach ($roles as $index => $role) {
    switch ($role) {
      case "manager":
        og_role_grant_permissions($index, array(
          'create h5p_content content',
        ));
        og_role_grant_permissions($index, array(
          'update own h5p_content content',
        ));
        og_role_grant_permissions($index, array(
          'update any h5p_content content',
        ));
        og_role_grant_permissions($index, array(
          'delete own h5p_content content',
        ));
        og_role_grant_permissions($index, array(
          'delete any h5p_content content',
        ));
        og_role_grant_permissions($index, array(
          'create opigno_scorm_quiz_question content',
        ));
        og_role_grant_permissions($index, array(
          'update own opigno_scorm_quiz_question content',
        ));
        og_role_grant_permissions($index, array(
          'update any opigno_scorm_quiz_question content',
        ));
        og_role_grant_permissions($index, array(
          'delete own opigno_scorm_quiz_question content',
        ));
        og_role_grant_permissions($index, array(
          'delete any opigno_scorm_quiz_question content',
        ));
        break;
      case "teacher":
        og_role_grant_permissions($index, array(
          'create h5p_content content',
        ));
        og_role_grant_permissions($index, array(
          'update own h5p_content content',
        ));
        og_role_grant_permissions($index, array(
          'delete own h5p_content content',
        ));
        og_role_grant_permissions($index, array(
          'create opigno_scorm_quiz_question content',
        ));
        og_role_grant_permissions($index, array(
          'update own opigno_scorm_quiz_question content',
        ));
        og_role_grant_permissions($index, array(
          'delete own opigno_scorm_quiz_question content',
        ));
        break;
    }
  }

  /* Existing group permissions */
  $existing_courses = node_load_multiple(array(), array(
    'type' => "course",
  ));
  foreach ($existing_courses as $courseid => $course) {
    $roles = og_roles("node", "course", $courseid, $force_group = FALSE, $include_all = TRUE);
    foreach ($roles as $index => $role) {
      switch ($role) {
        case "manager":
          og_role_grant_permissions($index, array(
            'create h5p_content content',
          ));
          og_role_grant_permissions($index, array(
            'update own h5p_content content',
          ));
          og_role_grant_permissions($index, array(
            'update any h5p_content content',
          ));
          og_role_grant_permissions($index, array(
            'delete own h5p_content content',
          ));
          og_role_grant_permissions($index, array(
            'delete any h5p_content content',
          ));
          og_role_grant_permissions($index, array(
            'create opigno_scorm_quiz_question content',
          ));
          og_role_grant_permissions($index, array(
            'update own opigno_scorm_quiz_question content',
          ));
          og_role_grant_permissions($index, array(
            'update any opigno_scorm_quiz_question content',
          ));
          og_role_grant_permissions($index, array(
            'delete own opigno_scorm_quiz_question content',
          ));
          og_role_grant_permissions($index, array(
            'delete any opigno_scorm_quiz_question content',
          ));
          break;
        case "teacher":
          og_role_grant_permissions($index, array(
            'create h5p_content content',
          ));
          og_role_grant_permissions($index, array(
            'update own h5p_content content',
          ));
          og_role_grant_permissions($index, array(
            'delete own h5p_content content',
          ));
          og_role_grant_permissions($index, array(
            'create opigno_scorm_quiz_question content',
          ));
          og_role_grant_permissions($index, array(
            'update own opigno_scorm_quiz_question content',
          ));
          og_role_grant_permissions($index, array(
            'delete own opigno_scorm_quiz_question content',
          ));
          break;
      }
    }
  }
  $distpath = drupal_get_path("profile", "opigno_lms");
  if (!empty($distpath)) {

    // Installs H5P Library
    $path = file_get_contents($distpath . "/h5plib/libraries.h5p");
    $temporary_file_path = 'public://' . variable_get('h5p_default_path', 'h5p') . '/temp/' . uniqid('h5p-');
    file_prepare_directory($temporary_file_path, FILE_CREATE_DIRECTORY);
    $temporary_file_name = $temporary_file_path . "/libraries.h5p";
    $file = file_save_data($path, $temporary_file_name, FILE_EXISTS_REPLACE);
    $_SESSION['h5p_upload'] = drupal_realpath($file->uri);
    $_SESSION['h5p_upload_folder'] = drupal_realpath($temporary_file_path);
    $validator = _h5p_get_instance('validator');
    $validator
      ->isValidPackage(TRUE, FALSE);
    $h5p_core = _h5p_get_instance('storage');
    $h5p_core
      ->savePackage(NULL, NULL, TRUE);
    unset($_SESSION['h5p_upload'], $_SESSION['h5p_upload_folder']);
  }
}
function opigno_quiz_app_update_7102($sandbox) {
  $schema_opigno_quiz_app_course_latest_viewed = array(
    'fields' => array(
      'course_nid' => array(
        'type' => 'int',
        'unsigned' => TRUE,
        'not null' => TRUE,
      ),
      'quiz_nid' => array(
        'type' => 'int',
        'unsigned' => TRUE,
        'not null' => TRUE,
      ),
      'uid' => array(
        'type' => 'int',
        'not null' => TRUE,
        'unsigned' => TRUE,
      ),
      'result_id' => array(
        'type' => 'int',
        'not null' => TRUE,
        'unsigned' => TRUE,
      ),
    ),
    'primary key' => array(
      'course_nid',
      'uid',
    ),
  );
  db_create_table('opigno_quiz_app_course_latest_viewed', $schema_opigno_quiz_app_course_latest_viewed);
}

/**
 * Updating permissions
 */
function opigno_quiz_app_update_7103($sandbox) {

  // All users should be able to view their own results / Achievements page
  $permission = array(
    'access own results',
  );
  $role_name = 'authenticated user';
  $role = user_role_load_by_name($role_name);
  if ($role->rid) {
    user_role_grant_permissions($role->rid, $permission);
  }

  // Admin users should be able to see all user results / Achievements page
  $permission = array(
    'access all results',
  );
  $role_name = 'administrator';
  $role = user_role_load_by_name($role_name);
  if ($role->rid) {
    user_role_grant_permissions($role->rid, $permission);
  }
}

/**
 * Put in this function all the strings that are not in a t() or st() function.
 */
function opigno_quiz_app_install_translations() {

  //
  // --- PATCHES
  // Quiz
  // https://www.drupal.org/files/issues/quiz_modify-quiz-to-lesson-in-ui-strings-2101063_4.patch
  t('There are !num revisions of this lesson that have been taken. Different revisions may have different scoring, difficulity and other differences affecting its statistics. Because of this you have to choose the revision you want to see statistics from.');
  t('This chart shows the distribution of the scores on this lesson.');
  t('This chart shows the status for all attempts made to answer this revision of the lesson.');
  t('This chart shows how many times the lesson has been taken the last !days days.');
  t('Lesson Grade Range');
  t('Lesson Top Scorers');
  t('Lesson Attendees');
  t('Lesson Status Chart');
  t('Module creates a report to analyse and compare the results of lesson attendees. The reports will be displayed visually using goolge chart API.');
  t('There are no statistics for this lesson (or lesson revision). This is probably because nobody has yet run this lesson (or lesson revision). If the lesson has multiple revisions, it is possible that the other revisions do have statistics. If this is the last revision, taking the lesson should generate some statistics.');
  t('The validator will transform the incoming lesson node id(s) into one or more lesson node revisions, depending on your selection.');
  t('When this agument is used, this box must be checked if the Lesson Status field is to work properly.');
  t('Question Status in Lesson');
  t('Lesson revision(s) to use');
  t('Latest: most recent version of the lesson ONLY.');
  t('Initial: original version of the lesson ONLY.');
  t('All: ALL versions of the lesson.');
  t('The filter will limit score results for a particular lesson node id(s) into one or more lesson node revision ids, depending on your selection.');
  t('Use Lesson Results');
  t('Use Lesson Questions');
  t('If you are looking to generate a list of either lesson questions or lesson results, you must select the appropriate option from this list.');
  t('Filter using the current user; only lesson results owned by the current user will be shown.');
  t('Used for Lesson Status');
  t('If you are using the Lesson Status, this box must be checked; otherwise, the field will not work properly.');
  t('Output will be limited to only include lesson results in this state. If the filter is exposed, the value set here will be used as the default. Note that "Any" is only useful for exposed filters.');
  t('Lessons are collections of questions that are taken and scored.');
  t('Lesson Version');
  t('Filter results to a specific subset of lesson versions.');
  t('The Revision ID of the Lesson Node.');
  t('The number of questions on this lesson that will be randomly selected.');
  t('The percentage of questions that must be correct before the lesson is passed.');
  t('Indicates whether lesson takers can go back to previous questions.');
  t('Indicates whether lesson takers will get feedback after every question.');
  t('The time limit on a lesson.');
  t('The first time a new lesson can be taken.');
  t('The last time a new lesson can be taken.');
  t('Indicates whether lesson is always available (Open and Close time are ignored).');
  t('The number of times a lesson can be taken.');
  t('Take lesson link');
  t('Allows users to take the lesson if available.');
  t('Lesson Questions');
  t('Lesson Node ID');
  t('The node id of the lesson to which the question is attached.');
  t('Lesson node id');
  t('The node revision id of the lesson to which the question is attached.');
  t('Lesson node revision');
  t('Field indicating the state of a question for the relevant lesson.');
  t('Filter results based on the question\'s status in the relevant lesson.');
  t('The number of questions assigned to the lesson.');
  t('Lesson Results');
  t('Lesson Node NID');
  t('The ID of the Lesson Node.');
  t('Filter results to a particular subset of lesson versions.');
  t('Lesson Node VID');
  t('The Version ID of the Lesson Node.');
  t('The ID of the user who took this lesson.');
  t('Filter on the user who owns the lesson results.');
  t('Lesson Start Time');
  t('Time the Lesson was started.');
  t('Lesson End Time');
  t('Time the lesson was finished.');
  t('Score on the lesson.');
  t('Filter the results based on the score of the lesson.');
  t('Indicates whether or not a lesson result is valid. This is a simple database boolean; the meaning of the "valid" flag should vary according to your use case.');
  t('Aggregate scores on lessons using a variety of different algorithms.');
  t('Indicates whether or not a lesson result is evaluated. This is a simple database boolean; this "evaluated" flag indicates if the lesson result has been graded.');
  t('Lesson State');
  t('The state of the lesson for the provided user. Calculated on the fly; can be "Finished," "In Progress," or "Not Started".');
  t('Filter the results based on the state of lessons with respect to users (i.e., whether they have started, finished, or are in progress on the lesson).');
  t('Lesson Results by Question');
  t('Lesson Answer Time');
  t('Indicates whether or not a lesson question was skipped.');
  t('The ID identifying a particular set of lesson results. This ID is unique with respect to the lesson nid and vid of the lesson, uid of the lessonee, and the take of the lesson.');
  t('Lesson Multichoice Answers');
  t('There should be only one unanswered question for the lesson.');
  t('Matching question type for lesson module.');
  t('A question type for the lesson module: allows you to create matching type questions, which connect terms with one another.');
  t('Matching question type for lesson module. A question type for the lesson module: allows you to create matching type questions, which connect terms with one another.');
  t('Present alternatives in random order when lesson is being taken.');
  t('This provides multiple choice questions for use by the Lesson module.');
  t('This provides drag and drop question types with lines for the Lesson module.');
  t('Provides directions which can be inserted alongside questions in a lesson.');
  t('Slide');
  t('Slides allow you to drop in directions anywhere in a lesson. You can also use them to insert a confirmation step at the end of the lesson.');
  t('Add a title that will help distinguish this question from other questions. This will not be seen during the lesson.');
  t('Fieldset for adding a question directly into lessons');
  t('You have created a new revision of a question that belongs to %num lessons. Choose what you want to do with the different lessons.');
  t('If a lesson has been answered you should make a new revision to ensure that existing answer statistics and reports remain correct.');
  t('This module provides a scale question type for Lesson. It may be used to construct surveys.');
  t('Lesson questions that allow a user to choose from a scale.');
  t('This module provides a short answer question type for Lesson.');
  t('Lesson questions that allow a user to enter a line of text.');
  t('Lesson questions that allow a user to select "true" or "false" as his response to a statement.');
  t('Lesson');
  t('It is strongly recommended that auto revisioning is always on. It makes sure that when a question or lesson is changed a new revision is created if the current revision has been answered. If this feature is switched off result reports might be broken because a users saved answer might be connected to a wrong version of the lesson and/or question she was answering. All sorts of errors might appear.');
  t('Supply a number of days to calculate the default close date for new lessons.');
  t('Allow lesson creators to set a pass/fail option when creating a @quiz.');
  t('Check this to display the pass/fail options in the @quiz form. If you want to prohibit other lesson creators from changing the default pass/fail percentage, uncheck this option.');
  t('Set the maximum number of result options (categorizations for scoring a lesson). Set to 0 to disable result options.');
  t('Remove Incomplete Lesson Records (older than)');
  t('Number of days that you like to keep the incomplete lesson records');
  t('Lessons can integrate with other d.o modules like !views, !cck, !userpoints and !jquery_countdown. Here you can configure the way Lesson integrates with other modules. Disabled checkboxes indicates that modules are not enabled/installed');
  t('!userpoints is an <strong>optional</strong> module for Lesson. It provides ways for users to gain or lose points for performing certain actions on your site like attending @quiz. You will need to install the !userpoints module to use this feature.');
  t('!jquery_countdown is an <strong>optional</strong> module for Lesson. It is used to display a timer when taking a lesson. Without this timer, the user will not know how long he or she has left to complete the @quiz');
  t('Control aspects of the Lesson module\'s display');
  t('Change the name of the lesson type. Do you call it <em>test</em> or <em>assessment</em> instead? Change the display name of the module to something else. Currently, it is called @quiz. By default, it is called <em>Lesson</em>.');
  t('Send results to lesson author/attendee via e-mail. Configure e-mail subject and body.');
  t('E-mail results to lesson takers');
  t('Check this to send users their results at the end of a lesson.');
  t('This format will be used when sending lesson results at the end of a lesson.');
  t('E-mail for Lesson Authors');
  t('E-mail all results to lesson author.');
  t('Check this to send lesson results for all users to the lesson author.');
  t('This format will be used when sending lesson results at the end of a lesson. Authors and lesson takers gets the same format.');
  t('This format will be used when sending lesson results at the end of a lesson. !title(lesson title), !sitename, !taker(lesson takers username), !date(time when lesson was finished), !minutes(How many minutes the lesson taker spent taking the lesson), !desc(description of the lesson), !correcst(points attained), !total(max score for the lesson), !percentage(percentage score), !url(url to the result page) and !author are placeholders.');
  t('Default values for the lesson creation form can be edited <a href="!url">here</a>');
  t('The default number of days before a lesson is closed must be a number greater than 0.');
  t('The lesson name must be plain text.');
  t('Here you can change the default lesson settings for new users.');
  t('The category you are trying to add has already been added to this lesson.');
  t('Questions in this lesson');
  t('There are currently no questions in this lesson. Assign existing questions by using the question browser below. You can also use the links above to create new questions.');
  t('The number of questions to be randomly selected each time someone takes this lesson');
  t('This lesson has been answered. To maintain correctnes of existing answer reports changes should be saved as a new revision.');
  t('Allow question status changes to create a new revision of the lesson?');
  t('Do not show lessons in progress');
  t('Create interactive lessons for site visitors');
  t('Some of the updated settings may not apply to lesson being taken already. To see all changes in action you need to start again.');
  t('Take lesson button');
  t('Lesson summary');
  t('Fieldset for customizing how a lesson is taken');
  t('Fieldset for customizing when a lesson is available');
  t('Fieldset for customizing summaries in the lesson reports');
  t('Fieldset for customizing result comments in lesson reports');
  t('Start lesson');
  t('The difference between "random order" and "random questions" is that with "random questions" questions are drawn randomly from a pool of questions. With "random order" the lesson will always consist of the same questions. With "Categorized random questions" you can choose several terms questions should be drawn from, and you can also choose how many questions that should be drawn from each, and max score for each term.');
  t('The number of times a user is allowed to take the @lesson. <strong>Anonymous users are only allowed to take quizzes that allow an unlimited number of attempts.</strong>');
  t('Lesson Addons Properties');
  t('Set the maximum allowed time in seconds for this @lesson. Use 0 for no limit.');
  t('Show this result for scored lessons in this range (0-100).');
  t('If this box is checked most of the quiz specific settings you have made will be remembered and will be your default settings next time you create a lesson.');
  t('!taker attended the lesson !title on !date');
  t('You attended the lesson !title on !date');
  t('This lesson only allows %num_attempts attempts. Anonymous users can only access lessons that allows an unlimited number of attempts.');
  t('This lesson is closed');
  t('The user passed this lesson.');
  t('The user failed this lesson.');
  t('the user completed this lesson.');
  t('Note that this lesson is set to only keep each users best answer.');
  t('This lesson has not been scored yet.');
  t('Thanks for taking the lesson!');

  // https://www.drupal.org/files/add_plural_quiz_name-937430-8.patch
  t('Display name');
  t('The plural variant of your quiz name.');

  // https://www.drupal.org/files/issues/quiz-questiontostep-2185205-1.patch
  t('Step <span id="quiz-question-number">!x</span> of <span id="quiz-num-questions">@y</span>');

  // https://www.drupal.org/files/issues/quiz_2190283.patch
  t('The number of questions for this quiz have changed. You will have to start over.');

  // Cloze
  // http://drupal.org/files/issues/cloze_change_question_type_name-2249881-4.patch
  t('This module provides a fill in the blanks question type for Quiz.');
  t('Fill in the blanks question');

  //
  // --- FIELDS
  // opigno_quiz_app.install
  t('Quiz type');
  t('Sets the type of this lesson. Can be <em>theory</em> (containing theoretical slides), <em>quiz</em> (assessment, exam) and <em>mix</em> (containing both theoretical slides, SCORM packages, H5P rich contents, and assessments)');
  t('Calendar Date');
  t('Add to calendar');
  t('Add reminder to calendar');
  t('Required quiz');
  t('Defines a required quiz for this course. Users cannot finish the course without passing this quiz.');
  t('Quiz weight');
  t('Sets the weight of this quiz for the final course assessment. Leave at 0 if this quiz should not be taken into account for the final grade.');
  t('Quiz');
  t('Theory');
  t('Mix');
}

Functions

Namesort descending Description
opigno_quiz_app_enable_calendar_integration Enable Calendar App integration.
opigno_quiz_app_install Implements hook_install().
opigno_quiz_app_install_translations Put in this function all the strings that are not in a t() or st() function.
opigno_quiz_app_schema Implements hook_schema().
opigno_quiz_app_update_7101 Enable h5p module
opigno_quiz_app_update_7102
opigno_quiz_app_update_7103 Updating permissions