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

src/Controller/ApiController.php
<?php

namespace Drupal\upsc_quiz\Controller;

use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Database\Connection;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;

/**
 * API Controller for UPSC Quiz AJAX endpoints.
 */
class ApiController extends ControllerBase {

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

  /**
   * Constructs an ApiController object.
   *
   * @param \Drupal\Core\Database\Connection $database
   *   The database connection.
   */
  public function __construct(Connection $database) {
    $this->database = $database;
  }

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

  /**
   * General API endpoint.
   *
   * @param \Symfony\Component\HttpFoundation\Request $request
   *   The request object.
   *
   * @return \Symfony\Component\HttpFoundation\JsonResponse
   *   JSON response.
   */
  public function api(Request $request) {
    $method = $request->getMethod();
    $action = $request->query->get('action') ?: $request->request->get('action');

    switch ($action) {
      case 'get_questions':
        return $this->getQuestions($request);

      case 'submit_quiz':
        return $this->submitQuiz($request);

      case 'get_stats':
        return $this->getUserStats($request);

      default:
        return new JsonResponse(['error' => 'Invalid action'], 400);
    }
  }

  /**
   * Get questions API endpoint.
   *
   * @param \Symfony\Component\HttpFoundation\Request $request
   *   The request object.
   *
   * @return \Symfony\Component\HttpFoundation\JsonResponse
   *   JSON response with questions.
   */
  public function getQuestions(Request $request) {
    $section = $request->query->get('section');
    $limit = $request->query->get('limit', 0);
    $randomize = $request->query->get('randomize', FALSE);

    $query = $this->database->select('upsc_quiz_questions', 'q')
      ->fields('q', ['id', 'section', 'question', 'options', 'correct_answer', 'explanation', 'difficulty'])
      ->condition('status', 1);

    if ($section && $section !== 'all') {
      $query->condition('section', $section);
    }

    if ($randomize) {
      $query->orderRandom();
    } else {
      $query->orderBy('weight', 'ASC');
      $query->orderBy('id', 'ASC');
    }

    if ($limit > 0) {
      $query->range(0, $limit);
    }

    $questions = $query->execute()->fetchAll();

    $formatted_questions = [];
    foreach ($questions as $question) {
      $formatted_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,
      ];
    }

    return new JsonResponse([
      'success' => TRUE,
      'questions' => $formatted_questions,
      'total' => count($formatted_questions),
    ]);
  }

  /**
   * Submit quiz API endpoint.
   *
   * @param \Symfony\Component\HttpFoundation\Request $request
   *   The request object.
   *
   * @return \Symfony\Component\HttpFoundation\JsonResponse
   *   JSON response with results.
   */
  public function submitQuiz(Request $request) {
    $current_user = $this->currentUser();
    
    if ($current_user->isAnonymous()) {
      return new JsonResponse(['error' => 'Must be logged in to submit quiz'], 403);
    }

    $data = json_decode($request->getContent(), TRUE);
    
    if (!$data) {
      return new JsonResponse(['error' => 'Invalid data'], 400);
    }

    // Validate required fields
    $required_fields = ['mode', 'answers', 'timeSpent', 'totalQuestions'];
    foreach ($required_fields as $field) {
      if (!isset($data[$field])) {
        return new JsonResponse(['error' => "Missing required field: $field"], 400);
      }
    }

    // Calculate results
    $results = $this->calculateQuizResults($data);
    
    // Save attempt to database
    $attempt_id = upsc_quiz_save_attempt($current_user->id(), [
      'mode' => $data['mode'],
      'section' => $data['section'] ?? 'all',
      'score' => $results['correct'],
      'total_questions' => $data['totalQuestions'],
      'time_spent' => $data['timeSpent'],
      'answers' => $data['answers'],
      'results' => $results,
    ]);

    return new JsonResponse([
      'success' => TRUE,
      'attempt_id' => $attempt_id,
      'results' => $results,
      'redirect_url' => "/quiz/results/$attempt_id",
    ]);
  }

  /**
   * Get user statistics API endpoint.
   *
   * @param \Symfony\Component\HttpFoundation\Request $request
   *   The request object.
   *
   * @return \Symfony\Component\HttpFoundation\JsonResponse
   *   JSON response with user stats.
   */
  public function getUserStats(Request $request) {
    $current_user = $this->currentUser();
    
    if ($current_user->isAnonymous()) {
      return new JsonResponse(['error' => 'Must be logged in'], 403);
    }

    $stats = upsc_quiz_get_user_stats($current_user->id());
    
    return new JsonResponse([
      'success' => TRUE,
      'stats' => $stats,
    ]);
  }

  /**
   * Calculate quiz results from submitted data.
   *
   * @param array $data
   *   The submitted quiz data.
   *
   * @return array
   *   Calculated results.
   */
  private function calculateQuizResults(array $data) {
    $answers = $data['answers'];
    $question_ids = array_keys($answers);
    
    // Get correct answers from database
    $questions = $this->database->select('upsc_quiz_questions', 'q')
      ->fields('q', ['id', 'section', 'correct_answer'])
      ->condition('id', $question_ids, 'IN')
      ->execute()
      ->fetchAllAssoc('id');

    $results = [
      'totalQuestions' => $data['totalQuestions'],
      'answered' => count($answers),
      'correct' => 0,
      'incorrect' => 0,
      'skipped' => $data['totalQuestions'] - count($answers),
      'sections' => [],
      'timeSpent' => $data['timeSpent'],
    ];

    foreach ($answers as $question_id => $user_answer) {
      if (!isset($questions[$question_id])) {
        continue;
      }

      $question = $questions[$question_id];
      $section = $question->section;
      
      // Initialize section if not exists
      if (!isset($results['sections'][$section])) {
        $results['sections'][$section] = [
          'total' => 0,
          'correct' => 0,
          'incorrect' => 0,
          'skipped' => 0,
        ];
      }

      $results['sections'][$section]['total']++;

      if ($user_answer === NULL) {
        $results['skipped']++;
        $results['sections'][$section]['skipped']++;
      } elseif ($user_answer == $question->correct_answer) {
        $results['correct']++;
        $results['sections'][$section]['correct']++;
      } else {
        $results['incorrect']++;
        $results['sections'][$section]['incorrect']++;
      }
    }

    return $results;
  }

}

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

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