upsc_quiz-1.0.x-dev/upsc_quiz.install

upsc_quiz.install
<?php

/**
 * @file
 * Install, update and uninstall functions for the UPSC Quiz module.
 */

/**
 * Implements hook_schema().
 */
function upsc_quiz_schema() {
  $schema = [];

  // Table for storing quiz questions
  $schema['upsc_quiz_questions'] = [
    'description' => 'Stores quiz questions with their options and correct answers.',
    'fields' => [
      'id' => [
        'type' => 'serial',
        'not null' => TRUE,
        'description' => 'Primary Key: Unique question ID.',
      ],
      'section' => [
        'type' => 'varchar',
        'length' => 100,
        'not null' => TRUE,
        'description' => 'The quiz section (Polity, History, etc.).',
      ],
      'question' => [
        'type' => 'text',
        'not null' => TRUE,
        'description' => 'The question text.',
      ],
      'options' => [
        'type' => 'text',
        'size' => 'medium',
        'not null' => TRUE,
        'description' => 'JSON encoded options array.',
        'serialize' => TRUE,
      ],
      'correct_answer' => [
        'type' => 'varchar',
        'length' => 1,
        'not null' => TRUE,
        'description' => 'The correct answer (A, B, C, or D).',
      ],
      'explanation' => [
        'type' => 'text',
        'not null' => FALSE,
        'description' => 'Optional explanation for the answer.',
      ],
      'difficulty' => [
        'type' => 'int',
        'size' => 'tiny',
        'not null' => TRUE,
        'default' => 1,
        'description' => 'Question difficulty level (1-5).',
      ],
      'weight' => [
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0,
        'description' => 'Weight for ordering questions.',
      ],
      'status' => [
        'type' => 'int',
        'size' => 'tiny',
        'not null' => TRUE,
        'default' => 1,
        'description' => 'Published status (0 = unpublished, 1 = published).',
      ],
      'created' => [
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0,
        'description' => 'The Unix timestamp when the question was created.',
      ],
      'changed' => [
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0,
        'description' => 'The Unix timestamp when the question was most recently saved.',
      ],
    ],
    'primary key' => ['id'],
    'indexes' => [
      'section' => ['section'],
      'status' => ['status'],
      'difficulty' => ['difficulty'],
      'weight' => ['weight'],
    ],
  ];

  // Table for storing quiz attempts
  $schema['upsc_quiz_attempts'] = [
    'description' => 'Stores user quiz attempts and their results.',
    'fields' => [
      'id' => [
        'type' => 'serial',
        'not null' => TRUE,
        'description' => 'Primary Key: Unique attempt ID.',
      ],
      'uid' => [
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0,
        'description' => 'The user ID who took the quiz.',
      ],
      'session_id' => [
        'type' => 'varchar',
        'length' => 128,
        'not null' => TRUE,
        'description' => 'Session ID for anonymous users.',
      ],
      'section' => [
        'type' => 'varchar',
        'length' => 100,
        'not null' => TRUE,
        'description' => 'The quiz section attempted.',
      ],
      'score' => [
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0,
        'description' => 'Final score achieved.',
      ],
      'total_questions' => [
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0,
        'description' => 'Total number of questions in the attempt.',
      ],
      'correct_answers' => [
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0,
        'description' => 'Number of correct answers.',
      ],
      'time_taken' => [
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0,
        'description' => 'Time taken to complete the quiz in seconds.',
      ],
      'answers' => [
        'type' => 'text',
        'size' => 'medium',
        'not null' => FALSE,
        'description' => 'JSON encoded user answers.',
      ],
      'results' => [
        'type' => 'text',
        'size' => 'medium',
        'not null' => FALSE,
        'description' => 'JSON encoded quiz results.',
      ],
      'quiz_mode' => [
        'type' => 'varchar',
        'length' => 50,
        'not null' => TRUE,
        'default' => 'practice',
        'description' => 'Quiz mode (practice, exam, section).',
      ],
      'completed' => [
        'type' => 'int',
        'size' => 'tiny',
        'not null' => TRUE,
        'default' => 0,
        'description' => 'Whether the quiz was completed (0 = incomplete, 1 = completed).',
      ],
      'created' => [
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0,
        'description' => 'The Unix timestamp when the quiz was started.',
      ],
      'finished' => [
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0,
        'description' => 'The Unix timestamp when the quiz was finished.',
      ],
    ],
    'primary key' => ['id'],
    'indexes' => [
      'uid' => ['uid'],
      'section' => ['section'],
      'completed' => ['completed'],
      'created' => ['created'],
      'quiz_mode' => ['quiz_mode'],
    ],
  ];

  // Table for storing individual question responses
  $schema['upsc_quiz_responses'] = [
    'description' => 'Stores individual question responses for each quiz attempt.',
    'fields' => [
      'id' => [
        'type' => 'serial',
        'not null' => TRUE,
        'description' => 'Primary Key: Unique response ID.',
      ],
      'attempt_id' => [
        'type' => 'int',
        'not null' => TRUE,
        'description' => 'Reference to the quiz attempt.',
      ],
      'question_id' => [
        'type' => 'int',
        'not null' => TRUE,
        'description' => 'Reference to the question.',
      ],
      'user_answer' => [
        'type' => 'varchar',
        'length' => 1,
        'not null' => FALSE,
        'description' => 'The answer selected by the user (A, B, C, or D).',
      ],
      'is_correct' => [
        'type' => 'int',
        'size' => 'tiny',
        'not null' => TRUE,
        'default' => 0,
        'description' => 'Whether the answer was correct (0 = incorrect, 1 = correct).',
      ],
      'time_spent' => [
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0,
        'description' => 'Time spent on this question in seconds.',
      ],
      'answered_at' => [
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0,
        'description' => 'The Unix timestamp when the question was answered.',
      ],
    ],
    'primary key' => ['id'],
    'indexes' => [
      'attempt_id' => ['attempt_id'],
      'question_id' => ['question_id'],
      'is_correct' => ['is_correct'],
    ],
    'foreign keys' => [
      'attempt' => [
        'table' => 'upsc_quiz_attempts',
        'columns' => ['attempt_id' => 'id'],
      ],
      'question' => [
        'table' => 'upsc_quiz_questions',
        'columns' => ['question_id' => 'id'],
      ],
    ],
  ];

  // Table for storing analytics data
  $schema['upsc_quiz_analytics'] = [
    'description' => 'Stores analytics data for quiz performance tracking.',
    'fields' => [
      'id' => [
        'type' => 'serial',
        'not null' => TRUE,
        'description' => 'Primary Key: Unique analytics ID.',
      ],
      'section' => [
        'type' => 'varchar',
        'length' => 100,
        'not null' => TRUE,
        'description' => 'The quiz section.',
      ],
      'question_id' => [
        'type' => 'int',
        'not null' => TRUE,
        'description' => 'Reference to the question.',
      ],
      'total_attempts' => [
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0,
        'description' => 'Total number of times this question was attempted.',
      ],
      'correct_attempts' => [
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0,
        'description' => 'Number of times this question was answered correctly.',
      ],
      'avg_time_spent' => [
        'type' => 'float',
        'not null' => TRUE,
        'default' => 0,
        'description' => 'Average time spent on this question.',
      ],
      'difficulty_rating' => [
        'type' => 'float',
        'not null' => TRUE,
        'default' => 0,
        'description' => 'Calculated difficulty based on performance.',
      ],
      'last_updated' => [
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0,
        'description' => 'The Unix timestamp when analytics were last updated.',
      ],
    ],
    'primary key' => ['id'],
    'unique keys' => [
      'section_question' => ['section', 'question_id'],
    ],
    'indexes' => [
      'section' => ['section'],
      'question_id' => ['question_id'],
      'difficulty_rating' => ['difficulty_rating'],
    ],
    'foreign keys' => [
      'question' => [
        'table' => 'upsc_quiz_questions',
        'columns' => ['question_id' => 'id'],
      ],
    ],
  ];

  return $schema;
}

/**
 * Implements hook_install().
 */
function upsc_quiz_install() {
  // Set default configuration values
  \Drupal::configFactory()->getEditable('upsc_quiz.settings')
    ->set('time_limit', 30)
    ->set('enable_analytics', TRUE)
    ->set('allow_retake', TRUE)
    ->set('show_correct_answers', TRUE)
    ->set('randomize_questions', FALSE)
    ->set('randomize_options', FALSE)
    ->set('questions_per_section', 10)
    ->set('notify_admin', FALSE)
    ->set('admin_email', '')
    ->set('cache_questions', TRUE)
    ->set('debug_mode', FALSE)
    ->save();

  // Insert sample questions for each section
  _upsc_quiz_insert_sample_questions();

  \Drupal::messenger()->addMessage(t('UPSC Quiz module has been installed successfully. Sample questions have been added to get you started.'));
}

/**
 * Implements hook_uninstall().
 */
function upsc_quiz_uninstall() {
  // Delete configuration
  \Drupal::configFactory()->getEditable('upsc_quiz.settings')->delete();
  
  \Drupal::messenger()->addMessage(t('UPSC Quiz module has been uninstalled. All quiz data has been removed.'));
}

/**
 * Helper function to insert sample questions.
 */
function _upsc_quiz_insert_sample_questions() {
  $database = \Drupal::database();
  $current_time = \Drupal::time()->getCurrentTime();

  // Sample questions for each section
  $sample_questions = [
    // Polity questions
    [
      'section' => 'Polity',
      'question' => 'Which article of the Indian Constitution deals with the Right to Education?',
      'option_a' => 'Article 19',
      'option_b' => 'Article 21A',
      'option_c' => 'Article 25',
      'option_d' => 'Article 29',
      'correct_answer' => 'B',
      'explanation' => 'Article 21A was inserted by the 86th Constitutional Amendment Act, 2002, which makes education a fundamental right for children aged 6-14 years.',
      'difficulty' => 2,
    ],
    [
      'section' => 'Polity',
      'question' => 'The President of India is elected by which method?',
      'option_a' => 'Direct election by people',
      'option_b' => 'Electoral College system',
      'option_c' => 'Parliament members only',
      'option_d' => 'Prime Minister nomination',
      'correct_answer' => 'B',
      'explanation' => 'The President is elected by an Electoral College consisting of elected members of both Houses of Parliament and Legislative Assemblies of states.',
      'difficulty' => 1,
    ],
    // History questions
    [
      'section' => 'History',
      'question' => 'The Quit India Movement was launched in which year?',
      'option_a' => '1940',
      'option_b' => '1942',
      'option_c' => '1944',
      'option_d' => '1946',
      'correct_answer' => 'B',
      'explanation' => 'The Quit India Movement was launched by Mahatma Gandhi on August 8, 1942, during World War II.',
      'difficulty' => 1,
    ],
    [
      'section' => 'History',
      'question' => 'Who was the founder of the Mauryan Empire?',
      'option_a' => 'Ashoka',
      'option_b' => 'Chandragupta Maurya',
      'option_c' => 'Bindusara',
      'option_d' => 'Samudragupta',
      'correct_answer' => 'B',
      'explanation' => 'Chandragupta Maurya founded the Mauryan Empire around 321 BCE with the help of Chanakya.',
      'difficulty' => 1,
    ],
    // Geography questions
    [
      'section' => 'Geography',
      'question' => 'Which is the longest river in India?',
      'option_a' => 'Yamuna',
      'option_b' => 'Godavari',
      'option_c' => 'Ganga',
      'option_d' => 'Narmada',
      'correct_answer' => 'C',
      'explanation' => 'The Ganga river is the longest river in India, flowing for about 2,525 kilometers.',
      'difficulty' => 1,
    ],
    [
      'section' => 'Geography',
      'question' => 'The Tropic of Cancer passes through how many Indian states?',
      'option_a' => '6',
      'option_b' => '7',
      'option_c' => '8',
      'option_d' => '9',
      'correct_answer' => 'C',
      'explanation' => 'The Tropic of Cancer passes through 8 Indian states: Gujarat, Rajasthan, Madhya Pradesh, Chhattisgarh, Jharkhand, West Bengal, Tripura, and Mizoram.',
      'difficulty' => 2,
    ],
    // Economics questions
    [
      'section' => 'Economics',
      'question' => 'What does GDP stand for?',
      'option_a' => 'Gross Domestic Product',
      'option_b' => 'General Domestic Product',
      'option_c' => 'Gross Development Product',
      'option_d' => 'General Development Product',
      'correct_answer' => 'A',
      'explanation' => 'GDP stands for Gross Domestic Product, which measures the total economic output of a country.',
      'difficulty' => 1,
    ],
    [
      'section' => 'Economics',
      'question' => 'The Reserve Bank of India was established in which year?',
      'option_a' => '1934',
      'option_b' => '1935',
      'option_c' => '1936',
      'option_d' => '1937',
      'correct_answer' => 'B',
      'explanation' => 'The Reserve Bank of India was established on April 1, 1935, under the Reserve Bank of India Act, 1934.',
      'difficulty' => 2,
    ],
    // General Science questions
    [
      'section' => 'General Science',
      'question' => 'What is the chemical symbol for Gold?',
      'option_a' => 'Go',
      'option_b' => 'Gd',
      'option_c' => 'Au',
      'option_d' => 'Ag',
      'correct_answer' => 'C',
      'explanation' => 'The chemical symbol for Gold is Au, derived from the Latin word "aurum".',
      'difficulty' => 1,
    ],
    [
      'section' => 'General Science',
      'question' => 'Which planet is known as the Red Planet?',
      'option_a' => 'Venus',
      'option_b' => 'Mars',
      'option_c' => 'Jupiter',
      'option_d' => 'Saturn',
      'correct_answer' => 'B',
      'explanation' => 'Mars is known as the Red Planet due to iron oxide (rust) on its surface.',
      'difficulty' => 1,
    ],
    // Current Affairs questions
    [
      'section' => 'Current Affairs',
      'question' => 'Who is the current Chief Justice of India (as of 2024)?',
      'option_a' => 'N.V. Ramana',
      'option_b' => 'U.U. Lalit',
      'option_c' => 'D.Y. Chandrachud',
      'option_d' => 'Ranjan Gogoi',
      'correct_answer' => 'C',
      'explanation' => 'Justice D.Y. Chandrachud is the current Chief Justice of India, appointed in November 2022.',
      'difficulty' => 2,
    ],
    [
      'section' => 'Current Affairs',
      'question' => 'Which country hosted the G20 summit in 2023?',
      'option_a' => 'Indonesia',
      'option_b' => 'India',
      'option_c' => 'Brazil',
      'option_d' => 'South Africa',
      'correct_answer' => 'B',
      'explanation' => 'India hosted the G20 summit in New Delhi in September 2023 under its G20 presidency.',
      'difficulty' => 1,
    ],
  ];

  // Insert sample questions
  foreach ($sample_questions as $weight => $question) {
    $question['weight'] = $weight;
    $question['status'] = 1;
    $question['created'] = $current_time;
    $question['changed'] = $current_time;
    
    $database->insert('upsc_quiz_questions')->fields($question)->execute();
  }
}

/**
 * Update 11001: Migrate schema to Drupal 11 standards.
 * 
 * Updates database schema to be compliant with Drupal 11 coding standards
 * and removes deprecated accessCheck(false) usage from queries.
 */
function upsc_quiz_update_11001() {
  $database = \Drupal::database();
  $schema = $database->schema();
  
  // Update upsc_quiz_questions table
  if ($schema->tableExists('upsc_quiz_questions')) {
    // Check if we need to migrate from individual option fields to JSON options field
    if ($schema->fieldExists('upsc_quiz_questions', 'option_a')) {
      // Add the new options field
      $options_field = [
        'type' => 'text',
        'size' => 'medium',
        'not null' => TRUE,
        'description' => 'JSON encoded options array.',
      ];
      $schema->addField('upsc_quiz_questions', 'options', $options_field);
      
      // Migrate data from individual option fields to JSON format
      $questions = $database->select('upsc_quiz_questions', 'q')
        ->fields('q', ['id', 'option_a', 'option_b', 'option_c', 'option_d'])
        ->execute();
        
      foreach ($questions as $question) {
        $options = [
          'A' => $question->option_a,
          'B' => $question->option_b,
          'C' => $question->option_c,
          'D' => $question->option_d,
        ];
        
        $database->update('upsc_quiz_questions')
          ->fields(['options' => json_encode($options)])
          ->condition('id', $question->id)
          ->execute();
      }
      
      // Drop old option fields
      $schema->dropField('upsc_quiz_questions', 'option_a');
      $schema->dropField('upsc_quiz_questions', 'option_b');
      $schema->dropField('upsc_quiz_questions', 'option_c');
      $schema->dropField('upsc_quiz_questions', 'option_d');
    }
  }
  
  // Update upsc_quiz_attempts table
  if ($schema->tableExists('upsc_quiz_attempts')) {
    // Add missing fields if they don't exist
    if (!$schema->fieldExists('upsc_quiz_attempts', 'answers')) {
      $answers_field = [
        'type' => 'text',
        'size' => 'medium',
        'not null' => FALSE,
        'description' => 'JSON encoded user answers.',
      ];
      $schema->addField('upsc_quiz_attempts', 'answers', $answers_field);
    }
    
    if (!$schema->fieldExists('upsc_quiz_attempts', 'results')) {
      $results_field = [
        'type' => 'text',
        'size' => 'medium',
        'not null' => FALSE,
        'description' => 'JSON encoded quiz results.',
      ];
      $schema->addField('upsc_quiz_attempts', 'results', $results_field);
    }
    
    if (!$schema->fieldExists('upsc_quiz_attempts', 'quiz_mode')) {
      $quiz_mode_field = [
        'type' => 'varchar',
        'length' => 50,
        'not null' => TRUE,
        'default' => 'practice',
        'description' => 'Quiz mode (practice, exam, section).',
      ];
      $schema->addField('upsc_quiz_attempts', 'quiz_mode', $quiz_mode_field);
    }
    
    // Rename 'started' to 'created' for consistency
    if ($schema->fieldExists('upsc_quiz_attempts', 'started') && 
        !$schema->fieldExists('upsc_quiz_attempts', 'created')) {
      $schema->changeField('upsc_quiz_attempts', 'started', 'created', [
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0,
        'description' => 'The Unix timestamp when the quiz was started.',
      ]);
    }
    
    // Drop session_id field if it exists (not used in current implementation)
    if ($schema->fieldExists('upsc_quiz_attempts', 'session_id')) {
      $schema->dropField('upsc_quiz_attempts', 'session_id');
    }
  }
  
  return t('Successfully updated UPSC Quiz schema for Drupal 11 compliance.');
}

/**
 * Update hook to add new fields or modify existing schema.
 */
function upsc_quiz_update_8001() {
  // Example update hook for future schema changes
  // This would be used when updating the module to add new features
}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc