public static function handleExportRequest()
 {
     $GLOBALS['Session']->requireAccountLevel('Staff');
     // This was causing a script timeout (30 seconds), this should help speed it up
     \Site::$debug = false;
     $sw = new SpreadsheetWriter();
     // fetch key objects from database
     $students = Student::getAllByListIdentifier(empty($_GET['students']) ? 'all' : $_GET['students']);
     $skills = Skill::getAll(['indexField' => 'ID']);
     $demonstrations = Demonstration::getAllByWhere('StudentID IN (' . implode(',', array_map(function ($Student) {
         return $Student->ID;
     }, $students)) . ')', ['order' => 'ID']);
     // build and output headers list
     $headers = ['Timestamp', 'Submitted by', 'ID', 'Name', 'Type of experience', 'Context', 'Perfromance task', 'Artifact', 'Competency', 'Standard', 'Rating', 'Level', 'Mapping'];
     $sw->writeRow($headers);
     // one row for each demonstration standard
     foreach ($demonstrations as $Demonstration) {
         $row = [date('Y-m-d H:i', $Demonstration->Created), $Demonstration->Creator->FullName, $Demonstration->Student->StudentNumber, $Demonstration->Student->FullName, $Demonstration->ExperienceType, $Demonstration->Context, $Demonstration->PerformanceType, $Demonstration->ArtifactURL];
         $demonstrationSkills = DemonstrationSkill::getAllByField('DemonstrationID', $Demonstration->ID);
         // Don't rebuild the row for each standard demonstrated, just overwrite the last set of values
         foreach ($demonstrationSkills as $DemonstrationSkill) {
             $skill = $skills[$DemonstrationSkill->SkillID];
             $row[8] = $skill->Competency->Code;
             $row[9] = $skill->Code;
             $row[10] = $DemonstrationSkill->Level > 0 ? $DemonstrationSkill->Level : 'M';
             $row[11] = 9;
             $row[12] = '';
             $sw->writeRow($row);
         }
     }
 }
 public static function handleDashboardRequest()
 {
     if (!empty($_GET['content-area'])) {
         if (ctype_digit($_GET['content-area'])) {
             $ContentArea = ContentArea::getByID($_GET['content-area']);
         } else {
             $ContentArea = ContentArea::getByCode($_GET['content-area']);
         }
     }
     if (!empty($_GET['students'])) {
         try {
             $students = Student::getAllByListIdentifier($_GET['students']);
         } catch (\Exception $e) {
             return static::throwNotFoundError('Unable to load students list: ' . $e->getMessage());
         }
     }
     return static::respond('teacher-dashboard', ['ContentArea' => $ContentArea, 'students' => $students]);
 }
 public static function handleExportRequest()
 {
     $GLOBALS['Session']->requireAccountLevel('Staff');
     // This was causing a script timeout (30 seconds), this should help speed it up
     \Site::$debug = false;
     $sw = new SpreadsheetWriter();
     // fetch key objects from database
     $students = Student::getAllByListIdentifier(empty($_GET['students']) ? 'all' : $_GET['students']);
     $contentAreas = ContentArea::getAll(['order' => 'Code']);
     // collect counts of all missing demonstrations by student+competency
     try {
         $missingResults = DB::allRecords('SELECT StudentID, CompetencyID, SUM(neededDemonstrationsMissed) AS totalNeededDemonstrationsMissed' . ' FROM (' . '  SELECT' . '    Demonstration.StudentID' . '    ,Skill.CompetencyID' . '    ,LEAST(' . '       GREATEST(Skill.DemonstrationsRequired - SUM(IF(DemonstrationSkill.Level != 0, 1, 0)), 0)' . '       ,SUM(IF(DemonstrationSkill.Level = 0, 1, 0))' . '    ) AS neededDemonstrationsMissed' . '   FROM `%s` Demonstration' . '   JOIN `%s` DemonstrationSkill' . '    ON DemonstrationSkill.DemonstrationID = Demonstration.ID' . '   JOIN `%s` Skill' . '    ON Skill.ID = DemonstrationSkill.SkillID' . '   WHERE Demonstration.StudentID IN (%s)' . '   GROUP BY Demonstration.StudentID, DemonstrationSkill.SkillID' . ' ) MissingDemonstrationsByStudentSkill' . ' GROUP BY StudentID, CompetencyID', [Demonstration::$tableName, DemonstrationSkill::$tableName, Skill::$tableName, implode(',', array_map(function ($Student) {
             return $Student->ID;
         }, $students))]);
         $missingDemonstrationsByStudentCompetency = [];
         foreach ($missingResults as $result) {
             $missingDemonstrationsByStudentCompetency[$result['StudentID']][$result['CompetencyID']] = intval($result['totalNeededDemonstrationsMissed']);
         }
     } catch (TableNotFoundException $e) {
         $missingDemonstrationsByStudentCompetency = [];
     }
     // build and output headers list
     $headers = ['Student Name', 'Student Number', 'Grade Level'];
     foreach ($contentAreas as $ContentArea) {
         foreach ($ContentArea->Competencies as $Competency) {
             $headers[] = $Competency->Code . '-Logged';
             $headers[] = $Competency->Code . '-Total';
             $headers[] = $Competency->Code . '-AVG';
         }
         $headers[] = $ContentArea->Code . '-Logged';
         $headers[] = $ContentArea->Code . '-Total';
         $headers[] = $ContentArea->Code . '-Missing';
         $headers[] = $ContentArea->Code . '-AVG';
     }
     $sw->writeRow($headers);
     // one row for each demonstration
     foreach ($students as $Student) {
         $row = [$Student->FullName, $Student->StudentNumber, 9];
         foreach ($contentAreas as $ContentArea) {
             $demonstrationsCounted = 0;
             $demonstrationsRequired = 0;
             $demonstrationsMissing = 0;
             $contentAreaAverageTotal = 0;
             foreach ($ContentArea->Competencies as $Competency) {
                 $competencyCompletion = $Competency->getCompletionForStudent($Student);
                 // Logged
                 $row[] = $competencyCompletion['demonstrationsCount'];
                 // Total
                 $row[] = $Competency->getTotalDemonstrationsRequired();
                 // Average
                 $row[] = $competencyCompletion['demonstrationsCount'] ? round($competencyCompletion['demonstrationsAverage'], 2) : null;
                 $demonstrationsCounted += $competencyCompletion['demonstrationsCount'];
                 $demonstrationsRequired += $Competency->getTotalDemonstrationsRequired();
                 // averages are weighted by number of demonstrations
                 $contentAreaAverageTotal += $competencyCompletion['demonstrationsAverage'] * $competencyCompletion['demonstrationsCount'];
                 if (isset($missingDemonstrationsByStudentCompetency[$Student->ID][$Competency->ID])) {
                     $demonstrationsMissing += $missingDemonstrationsByStudentCompetency[$Student->ID][$Competency->ID];
                 }
             }
             $row[] = $demonstrationsCounted;
             $row[] = $demonstrationsRequired;
             $row[] = $demonstrationsMissing;
             $row[] = $demonstrationsCounted ? round($contentAreaAverageTotal / $demonstrationsCounted, 2) : null;
         }
         $sw->writeRow($row);
     }
 }