public function questionRecommendationsAction($scope = 'unit', $groupingId = '3', $debug = false)
 {
     $this->view->disable();
     // Get our context (this takes care of starting the session, too)
     $context = $this->getDI()->getShared('ltiContext');
     if (!$context->valid) {
         echo '[{"error":"Invalid lti context"}]';
         return;
     }
     if (!isset($groupingId)) {
         echo '[{"error":"No scope grouping ID specified"}]';
         return;
     }
     $classHelper = new ClassHelper();
     $group1 = [];
     $group2 = [];
     $group3 = [];
     $group4 = [];
     // Get the list of questions associated with concepts for the given scope and grouping ID
     $questionRows = [];
     switch ($scope) {
         case "concept":
             // Filter based on concept
             $questionRows = MappingHelper::questionsInConcept($groupingId);
             break;
         case "unit":
             // Filter based on unit
             $questionRows = MappingHelper::questionsInConcepts(MappingHelper::conceptsInUnit($groupingId));
             break;
         default:
             // Allowing all would take too long
             echo '[{"error":"Invalid scope option"}]';
             return;
             break;
     }
     if ($debug) {
         echo "<pre>Getting information for these questions in scope {$scope} and ID {$groupingId}\n";
         print_r($questionRows);
     }
     $questions = [];
     // Get some info about each question
     foreach ($questionRows as $question) {
         // Get number of attempts and number of correct attempts
         $question["attempts"] = MasteryHelper::countAttemptsForQuestion($context->getUserName(), $question["OA Quiz ID"], $question["Question Number"], $debug);
         $question["correctAttempts"] = MasteryHelper::countCorrectAttemptsForQuestion($context->getUserName(), $question["OA Quiz ID"], $question["Question Number"], $debug);
         // Get amount of associated videos watched
         $question["videoPercentage"] = MasteryHelper::calculateUniqueVideoPercentageForQuestion($context->getUserName(), $question);
         // Variables used in the display table
         // This is one place where we're just using correct, not better correct, attempts
         $question["correct"] = $question["correctAttempts"]["correct"] > 0;
         $question["classAverageAttempts"] = $classHelper->calculateAverageAttemptsForQuestion($question["OA Quiz ID"], $question["Question Number"], $debug);
         $question["classViewedHint"] = $classHelper->calculateViewedHintPercentageForQuestion($question["OA Quiz ID"], $question["Question Number"], $debug);
         $question["classViewedAnswer"] = $classHelper->calculateViewedAnswerPercentageForQuestion($question["OA Quiz ID"], $question["Question Number"], $debug);
         $questions[] = $question;
     }
     // Fetch question texts for all questions in these assessments
     // Get the Open Assessments API endpoint from config
     $assessmentsEndpoint = $this->getDI()->getShared('config')->openassessments_endpoint;
     // Extract a list of assessment IDs from our list of questions. We'll get question texts for these.
     $assessmentIDs = ["assessment_ids" => array_values(array_unique(array_column($questions, "OA Quiz ID")))];
     $request = $assessmentsEndpoint . "api/question_text";
     //$request = "http://192.168.33.102/api/question_text";
     if ($debug) {
         echo "Fetching question texts for these assessment IDs:\n";
         print_r(array_column($questions, "OA Quiz ID"));
         print_r($assessmentIDs);
         echo $request;
     }
     #print_r($assessmentIDs);
     #echo json_encode($request);
     $session = curl_init($request);
     curl_setopt($session, CURLOPT_RETURNTRANSFER, true);
     curl_setopt($session, CURLOPT_POST, 1);
     curl_setopt($session, CURLOPT_POSTFIELDS, json_encode($assessmentIDs));
     $response = curl_exec($session);
     #echo json_encode($questionRows);
     // Catch curl errors
     if (curl_errno($session)) {
         $error = "Curl error: " . curl_error($session);
     }
     curl_close($session);
     #print_r($response);
     $questionTexts = json_decode($response, true);
     if ($debug) {
         print_r($questionTexts);
     }
     foreach ($questions as $key => $q) {
         // Make sure the question text exists before setting it
         $questions[$key]["display"] = isset($questionTexts[$q["OA Quiz ID"]][$q["Question Number"] - 1]) ? $questionTexts[$q["OA Quiz ID"]][$q["Question Number"] - 1] : "Error getting question text for #{$q["OA Quiz ID"]} # #{$q["Question Number"]}-1";
         // Avoid off-by-one error. The question id from statement object id will be 1 to n+1
         //$q["questionText"] = $questionText;
     }
     // Now go through the questions for each group and find matching questions
     foreach ($questions as $question) {
         // Group 1:
         // Questions with 0 attempts
         if ($question["attempts"] == 0) {
             $group1[] = $question;
         }
         // Group 2:
         // >0 attempts for each question
         // No correct statements without a show answer statement in the preceding minute for each question (correctAttempts < 1)
         // Watched less than half of the videos associated with each question
         if ($question["attempts"] > 0 && $question["correctAttempts"]["betterCorrect"] == 0 && $question["videoPercentage"] < 0.5) {
             $group2[] = $question;
         }
         // Group 3:
         // >0 attempts for each question
         // No correct statements without a show answer statement in the preceding minute for each question (correctAttempts < 1)
         // Watched more than half of the videos associated with each question
         if ($question["attempts"] > 0 && $question["correctAttempts"]["betterCorrect"] == 0 && $question["videoPercentage"] >= 0.5) {
             $group3[] = $question;
         }
         // Group 4:
         // >  0 correct statements without a show answer statement in the preceding minute for each question (correctAttempts > 0)
         // More than 1 attempt
         if ($question["correctAttempts"]["betterCorrect"] > 0 && $question["attempts"] > 1) {
             $group4[] = $question;
         }
     }
     if ($debug) {
         print_r($questions);
     }
     $result = ["group1" => $group1, "group2" => $group2, "group3" => $group3, "group4" => $group4];
     echo json_encode($result);
 }