upsc_quiz-1.0.x-dev/src/Controller/QuizController.php

src/Controller/QuizController.php
<?php

namespace Drupal\upsc_quiz\Controller;

use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Database\Connection;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Url;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;

/**
 * Controller for UPSC Quiz main functionality.
 */
class QuizController extends ControllerBase {

  /**
   * The database connection.
   *
   * @var \Drupal\Core\Database\Connection
   */
  protected $database;

  /**
   * The current user.
   *
   * @var \Drupal\Core\Session\AccountInterface
   */
  protected $currentUser;

  /**
   * Constructs a QuizController object.
   *
   * @param \Drupal\Core\Database\Connection $database
   *   The database connection.
   * @param \Drupal\Core\Session\AccountInterface $current_user
   *   The current user.
   */
  public function __construct(Connection $database, AccountInterface $current_user) {
    $this->database = $database;
    $this->currentUser = $current_user;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('database'),
      $container->get('current_user')
    );
  }

  /**
   * Main quiz page.
   *
   * @return array
   *   Render array for the quiz main page.
   */
  public function main() {
    // Check if user is logged in for saving progress
    if ($this->currentUser->isAnonymous()) {
      $this->messenger()->addWarning($this->t('Please log in to save your quiz progress and view statistics.'));
    }

    $build = [
      '#theme' => 'upsc_quiz_main',
      '#quiz_data' => $this->getQuizData(),
      '#user_data' => $this->getUserData(),
      '#settings' => $this->getQuizSettings(),
      '#attached' => [
        'library' => [
          'upsc_quiz/quiz-app',
          'upsc_quiz/quiz-styles',
        ],
        'drupalSettings' => [
          'upscQuiz' => [
            'userId' => $this->currentUser->id(),
            'isLoggedIn' => !$this->currentUser->isAnonymous(),
            'apiBase' => Url::fromRoute('upsc_quiz.api')->toString(),
            'sections' => $this->getAvailableSections(),
          ],
        ],
      ],
      '#cache' => [
        'contexts' => ['user'],
        'tags' => ['upsc_quiz:questions'],
      ],
    ];

    return $build;
  }

  /**
   * Section-specific quiz page.
   *
   * @param string $section
   *   The quiz section.
   *
   * @return array
   *   Render array for the section quiz page.
   */
  public function section($section) {
    $valid_sections = array_keys($this->getAvailableSections());
    
    if (!in_array($section, $valid_sections)) {
      throw new NotFoundHttpException();
    }

    $build = [
      '#theme' => 'upsc_quiz_main',
      '#quiz_data' => $this->getQuizData($section),
      '#user_data' => $this->getUserData(),
      '#settings' => $this->getQuizSettings(),
      '#attached' => [
        'library' => [
          'upsc_quiz/quiz-app',
          'upsc_quiz/quiz-styles',
        ],
        'drupalSettings' => [
          'upscQuiz' => [
            'userId' => $this->currentUser->id(),
            'isLoggedIn' => !$this->currentUser->isAnonymous(),
            'apiBase' => Url::fromRoute('upsc_quiz.api')->toString(),
            'selectedSection' => $section,
            'sections' => $this->getAvailableSections(),
          ],
        ],
      ],
      '#cache' => [
        'contexts' => ['user', 'url.path'],
        'tags' => ['upsc_quiz:questions', 'upsc_quiz:section:' . $section],
      ],
    ];

    return $build;
  }

  /**
   * Quiz results page.
   *
   * @param int $attempt_id
   *   The quiz attempt ID.
   *
   * @return array
   *   Render array for the results page.
   */
  public function results($attempt_id) {
    // Get attempt data
    $attempt = $this->database->select('upsc_quiz_attempts', 'a')
      ->fields('a')
      ->condition('id', $attempt_id)
      ->condition('uid', $this->currentUser->id())
      ->execute()
      ->fetchObject();

    if (!$attempt) {
      throw new NotFoundHttpException();
    }

    $results = json_decode($attempt->results, TRUE);
    $answers = json_decode($attempt->answers, TRUE);

    $build = [
      '#theme' => 'upsc_quiz_results',
      '#results' => $results,
      '#sections' => $this->getAvailableSections(),
      '#user_answers' => $answers,
      '#questions' => $this->getQuestionsForAttempt($attempt),
      '#attached' => [
        'library' => [
          'upsc_quiz/quiz-styles',
        ],
      ],
      '#cache' => [
        'contexts' => ['user'],
        'tags' => ['upsc_quiz:attempt:' . $attempt_id],
      ],
    ];

    return $build;
  }

  /**
   * User statistics page.
   *
   * @return array
   *   Render array for the user stats page.
   */
  public function userStats() {
    if ($this->currentUser->isAnonymous()) {
      return new RedirectResponse(Url::fromRoute('user.login')->toString());
    }

    $stats = upsc_quiz_get_user_stats($this->currentUser->id());
    
    // Get recent attempts
    $recent_attempts = $this->database->select('upsc_quiz_attempts', 'a')
      ->fields('a')
      ->condition('uid', $this->currentUser->id())
      ->orderBy('created', 'DESC')
      ->range(0, 10)
      ->execute()
      ->fetchAll();

    $build = [
      '#theme' => 'user_stats',
      '#stats' => $stats,
      '#recent_attempts' => $recent_attempts,
      '#sections' => $this->getAvailableSections(),
      '#attached' => [
        'library' => [
          'upsc_quiz/quiz-styles',
        ],
      ],
      '#cache' => [
        'contexts' => ['user'],
        'tags' => ['upsc_quiz:user_stats:' . $this->currentUser->id()],
      ],
    ];

    return $build;
  }

  /**
   * Get quiz data.
   *
   * @param string|null $section
   *   Optional section to filter by.
   *
   * @return array
   *   Quiz data array.
   */
  private function getQuizData($section = NULL) {
    $questions = upsc_quiz_get_questions_by_section($section);
    
    $quiz_data = [
      'questions' => [],
      'sections' => $this->getAvailableSections(),
      'total_questions' => count($questions),
    ];

    foreach ($questions as $question) {
      $quiz_data['questions'][] = [
        'id' => $question->id,
        'section' => $question->section,
        'question' => $question->question,
        'options' => json_decode($question->options, TRUE),
        'correct' => $question->correct_answer,
        'explanation' => $question->explanation,
        'difficulty' => $question->difficulty,
        'weight' => $question->weight,
      ];
    }

    return $quiz_data;
  }

  /**
   * Get user data.
   *
   * @return array
   *   User data array.
   */
  private function getUserData() {
    if ($this->currentUser->isAnonymous()) {
      return ['anonymous' => TRUE];
    }

    return [
      'anonymous' => FALSE,
      'uid' => $this->currentUser->id(),
      'name' => $this->currentUser->getAccountName(),
      'stats' => upsc_quiz_get_user_stats($this->currentUser->id()),
    ];
  }

  /**
   * Get quiz settings.
   *
   * @return array
   *   Quiz settings array.
   */
  private function getQuizSettings() {
    $config = $this->config('upsc_quiz.settings');
    
    return [
      'time_limit' => $config->get('time_limit') ?: 90,
      'questions_per_section' => $config->get('questions_per_section') ?: [],
      'enable_analytics' => $config->get('enable_analytics') ?: TRUE,
      'allow_retake' => $config->get('allow_retake') ?: TRUE,
      'show_correct_answers' => $config->get('show_correct_answers') ?: TRUE,
      'randomize_questions' => $config->get('randomize_questions') ?: FALSE,
      'randomize_options' => $config->get('randomize_options') ?: FALSE,
    ];
  }

  /**
   * Get available sections.
   *
   * @return array
   *   Array of available sections.
   */
  private function getAvailableSections() {
    return [
      'reasoning' => $this->t('Reasoning & Logic'),
      'english' => $this->t('English Language'),
      'polity' => $this->t('Indian Polity'),
      'history' => $this->t('History'),
      'geography' => $this->t('Geography'),
      'current-affairs' => $this->t('Current Affairs'),
    ];
  }

  /**
   * Get questions for a specific attempt.
   *
   * @param object $attempt
   *   The attempt object.
   *
   * @return array
   *   Array of questions used in the attempt.
   */
  private function getQuestionsForAttempt($attempt) {
    // This would typically be stored with the attempt
    // For now, get current questions by section
    return upsc_quiz_get_questions_by_section($attempt->section !== 'all' ? $attempt->section : NULL);
  }

}

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

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