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 handleCompetenciesRequest(ContentArea $ContentArea)
 {
     // get input students
     if (empty($_REQUEST['students'])) {
         $studentIds = [];
     } else {
         $studentIds = is_string($_REQUEST['students']) ? explode(',', $_REQUEST['students']) : $_REQUEST['students'];
     }
     $students = [];
     foreach ($studentIds as $studentId) {
         if (!ctype_digit($studentId)) {
             return static::throwInvalidRequestError('students must be identified by integer ID');
         }
         if (!($students[] = Student::getByID($studentId))) {
             return static::throwInvalidRequestError('student ID not found');
         }
     }
     // get data for all competencie
     $competencies = [];
     foreach ($ContentArea->Competencies as $Competency) {
         $competencyData = $Competency->getDetails(['totalDemonstrationsRequired', 'minimumAverage']);
         foreach ($students as $Student) {
             $competencyData['studentCompletions'][$Student->ID] = $Competency->getCompletionForStudent($Student);
         }
         $competencies[] = $competencyData;
     }
     #        // query per-student and per-competency completed demonstrations
     #        try {
     #            $studentCompetencies = DB::allRecords(
     #                'SELECT Demonstration.StudentID, Skill.ID, Skill.CompetencyID, LEAST(Skill.DemonstrationsRequired, COUNT(Demonstration.ID)) AS demonstrations'
     #                .' FROM (SELECT ID, CompetencyID, DemonstrationsRequired FROM `%s` WHERE CompetencyID IN (%s)) Skill'
     #                .' JOIN `%s` DemonstrationSkill'
     #                .'  ON DemonstrationSkill.SkillID = Skill.ID'
     #                .' JOIN (SELECT ID, StudentID FROM `%s` WHERE StudentID IN (%s)) Demonstration'
     #                .'  ON Demonstration.ID = DemonstrationSkill.DemonstrationID'
     #                .' GROUP BY StudentID, Skill.ID'
     #                ,[
     #                    Skill::$tableName
     #                    ,implode(',', array_keys($competencies))
     #                    ,DemonstrationSkill::$tableName
     #                    ,Demonstration::$tableName
     #                    ,implode(',', $students)
     #                ]
     #            );
     #        } catch (TableNotFoundException $e) {
     #            $studentCompetencies = [];
     #        }
     #
     #        // sort demonstrations into competencies array and index by student id
     #        foreach ($studentCompetencies AS $studentCompetency) {
     #            $competencies[$studentCompetency['CompetencyID']]['studentDemonstrations'][$studentCompetency['StudentID']] += (int)$studentCompetency['demonstrations'];
     #        }
     return static::respond('competencies', ['data' => $competencies]);
 }
 protected static function _getRequestedStudent()
 {
     if (!empty($_GET['student']) && $GLOBALS['Session']->hasAccountLevel('Staff')) {
         if (!($Student = Student::getByHandle($_GET['student']))) {
             return static::throwNotFoundError('Student not found');
         }
     } else {
         $Student = $GLOBALS['Session']->Person;
     }
     if (!$Student->isA(Student::class)) {
         return static::throwInvalidRequestError('Requested user is not a student');
     }
     return $Student;
 }
 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);
     }
 }