public function classConceptHistoryAction()
 {
     $config = $this->getDI()->getShared('config');
     if (!isset($_GET["p"])) {
         die("No history saver password provided.");
     }
     if ($_GET["p"] != $config->historySaverPassword) {
         die("Invalid history saver password provided.");
     }
     // We want to time this
     $startTime = microtime(true);
     $raw = false;
     $debug = false;
     $classHelper = new ClassHelper();
     $masteryHelper = new MasteryHelper();
     $allConcepts = MappingHelper::allConcepts();
     $studentIds = $classHelper->allStudents();
     //$studentIds = ["John Logie Baird"];
     foreach ($allConcepts as $concept) {
         $classHelper = new ClassHelper();
         $masteryHelper = new MasteryHelper();
         $studentIds = $classHelper->allStudents();
         $sum = 0;
         foreach ($studentIds as $student) {
             $sum += $masteryHelper->calculateUniqueVideoPercentageForConcept($student, $concept);
         }
         $avg = $sum / count($studentIds);
         echo $avg;
         $lecNum = $concept["Lecture Number"];
         $lastHistory = ClassConceptHistory::findFirst(["concept_id = {$lecNum}", "order" => "time_stored DESC"]);
         if (date("Y-m-d") == date("Y-m-d", strtotime($lastHistory->time_stored))) {
             echo "    History already saved today for concept #{$lecNum}\n";
             continue;
         }
         $scoreSum = 0;
         $scoreCount = 0;
         // Check if it's a concept in the future
         $today = strtotime("today");
         $includeZero = true;
         if (strtotime($concept["Date"]) > $today) {
             $includeZero = false;
         }
         // Calculate concept score for each student
         foreach ($studentIds as $studentId) {
             // Calculate score
             $score = $masteryHelper->calculateConceptMasteryScore($studentId, $concept["Lecture Number"], $debug);
             // Add score
             if ($score == 0) {
                 if ($includeZero) {
                     $scoreCount++;
                 }
             } else {
                 $scoreCount++;
                 $scoreSum += $score;
             }
         }
         // Calculate average
         $average = $scoreSum / $scoreCount;
         // Store concept average
         $conceptHistory = new ClassConceptHistory();
         $conceptHistory->concept_id = $concept["Lecture Number"];
         $conceptHistory->average_mastery = $average;
         $conceptHistory->videopercentage = $avg;
         if ($conceptHistory->create() == false) {
             echo "*** Error saving concept history for {$concept}\n";
         } else {
         }
     }
     // Print total time taken
     $endTime = microtime(true);
     echo "Execution time: " . ($endTime - $startTime) . " seconds\n";
 }
 public function masteryGraphAction($scope = 'all', $groupingId = '', $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;
     }
     $result = [];
     // Get the list of concepts for the given scope and grouping ID
     $concepts = [];
     switch ($scope) {
         case "unit":
             // Filter based on unit
             $concepts = MappingHelper::conceptsInUnit($groupingId);
             break;
         default:
             // All concepts
             $concepts = MappingHelper::allConcepts();
             break;
     }
     $masteryHelper = new MasteryHelper();
     foreach ($concepts as $c) {
         $score = $masteryHelper::calculateConceptMasteryScore($context->getUserName(), $c["Lecture Number"], $debug);
         if ($debug) {
             echo "Concept mapping info\n";
             print_r($c);
         }
         $result[] = ["id" => $c["Lecture Number"], "display" => $c["Concept Title"], "score" => $score, "unit" => $c["Unit Number"]];
     }
     echo json_encode($result);
 }
 public function conceptsAction($scope = 'all', $groupingId = '', $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;
     }
     $result = [];
     // Get the list of concepts for the given scope and grouping ID
     $concepts = [];
     switch ($scope) {
         case "concept":
             // Get a specific concept
             $conceptId = $groupingId;
             $concepts = array_filter(MappingHelper::allConcepts(), function ($concept) use($conceptId) {
                 return $concept["Lecture Number"] == $conceptId;
             });
             break;
         case "unit":
             // Filter based on unit
             $concepts = MappingHelper::conceptsInUnit($groupingId);
             break;
         default:
             // All concepts
             $concepts = MappingHelper::allConcepts();
             break;
     }
     $masteryHelper = new MasteryHelper();
     foreach ($concepts as $c) {
         $score = $masteryHelper::calculateConceptMasteryScore($context->getUserName(), $c["Lecture Number"], $debug);
         $videoPercentage = $masteryHelper::calculateUniqueVideoPercentageForConcept($context->getUserName(), $c["Lecture Number"], $debug);
         //$score = rand(0,100) / 10;
         //$videoPercentage = rand(0,100);
         if ($debug) {
             echo "Concept mapping info\n";
             print_r($c);
         }
         $result[] = ["id" => $c["Lecture Number"], "title" => $c["Concept Title"], "masteryScore" => $score, "videoPercentage" => $videoPercentage, "unit" => $c["Unit Number"]];
     }
     echo json_encode($result);
 }
 public function resourcesAction()
 {
     $this->tag->setTitle('Course Resources | Student Dashboard');
     $this->view->pageTitle = 'Course Resources | Student Dashboard';
     // Get our context (this takes care of starting the session, too)
     $context = $this->getDI()->getShared('ltiContext');
     // Get list of concepts
     $conceptsMapping = MappingHelper::allConcepts();
     $concepts = [];
     $resources = [];
     // Get list of resources for each concept
     foreach ($conceptsMapping as $c) {
         // Formatting for view
         $concepts[] = ["id" => $c["Lecture Number"], "title" => $c["Concept Title"], "date" => $c["Date"]];
         // Get resources for each of the concepts
         $conceptId = $c["Lecture Number"];
         $resourceLists[$conceptId] = MappingHelper::resourcesForConcept($conceptId);
         // Get videos for each of the concepts
         $videos = MappingHelper::videosForConcept($conceptId);
         // Format videos to be the same format as ayamel links from the resources.csv mapping
         foreach ($videos as $video) {
             $resourceLists[$conceptId][] = ["Lecture Number" => $video["Lecture Number"], "Resource Type" => "ayamel", "Resource Title" => $video["Video Title"], "Resource Link" => $video["Video ID"], "Resource Tracking Number" => $video["Video ID"]];
         }
     }
     // Figure out which concept to position the list at (based on the current day)
     $currentConceptID = $conceptsMapping[0]["Date"];
     // This is assuming that every concept has a date, and that they are listed in concepts.csv in chronological non-descending order
     // Find the first concept that's past today, and then use the previous concept
     $today = strtotime("today");
     foreach ($conceptsMapping as $concept) {
         if (strtotime($concept["Date"]) > $today) {
             break;
         } else {
             $currentConceptID = $concept["Lecture Number"];
             // If this concept has a date of today, then stop
             if (strtotime($concept["Date"]) == $today) {
                 break;
             }
         }
     }
     $this->view->concepts = $concepts;
     $this->view->resources = $resourceLists;
     $this->view->currentConceptID = $currentConceptID;
 }