This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
| 1 | #!/usr/bin/env php |
||
| 2 | <?php |
||
| 3 | |||
| 4 | define('IGNORE_UI', true); |
||
| 5 | |||
| 6 | require_once __DIR__ . '/../common.inc.php'; |
||
| 7 | require_once __DIR__ . '/../constants.inc.php'; |
||
| 8 | |||
| 9 | use smtech\GradingAnalytics\Toolbox; |
||
| 10 | use smtech\CanvasPest\CanvasPest; |
||
| 11 | |||
| 12 | // http://stackoverflow.com/a/21896310 |
||
| 13 | function hoursRange($lower = 0, $upper = 86400, $step = 3600, $keyFormat = '', $value = '', $valueIsFormat = false) |
||
| 14 | { |
||
| 15 | $times = array(); |
||
| 16 | |||
| 17 | if (empty( $value ) && $valueIsFormat) { |
||
| 18 | $value = 'g:i a'; |
||
| 19 | } |
||
| 20 | |||
| 21 | if (empty($keyFormat)) { |
||
| 22 | $keyFormat = 'g:i a'; |
||
| 23 | } |
||
| 24 | |||
| 25 | foreach (range( $lower, $upper, $step ) as $increment) { |
||
| 26 | $increment = gmdate( $keyFormat, $increment ); |
||
| 27 | |||
| 28 | list( $hour, $minutes ) = explode( ':', $increment ); |
||
| 29 | |||
| 30 | $date = new DateTime( $hour . ':' . $minutes ); |
||
| 31 | |||
| 32 | $times[(string) $increment] = ($valueIsFormat ? $date->format( $value ) : $value); |
||
| 33 | } |
||
| 34 | |||
| 35 | return $times; |
||
| 36 | } |
||
| 37 | |||
| 38 | function collectStatistics($term, Toolbox $toolbox) |
||
| 39 | { |
||
| 40 | $courses = $toolbox->api_get( |
||
| 41 | '/accounts/' . $toolbox->config(Toolbox::TOOL_CANVAS_ACCOUNT_ID) . '/courses', |
||
| 42 | array( |
||
| 43 | 'with_enrollments' => 'true', |
||
| 44 | 'enrollment_term_id' => $term |
||
| 45 | ) |
||
| 46 | ); |
||
| 47 | |||
| 48 | // so that everything has a consistent benchmark |
||
| 49 | $timestamp = time(); |
||
| 50 | |||
| 51 | foreach ($courses as $course) { |
||
| 52 | $statistic = array( |
||
| 53 | 'timestamp' => date(DATE_ISO8601, $timestamp), |
||
| 54 | 'course[id]' => $course['id'], |
||
| 55 | 'course[name]' => $course['name'], |
||
| 56 | 'course[account_id]' => $course['account_id'], |
||
| 57 | 'gradebook_url' => $_SESSION[CANVAS_INSTANCE_URL] . "/courses/{$course['id']}/gradebook2", |
||
| 58 | 'assignments_due_count' => 0, |
||
| 59 | 'dateless_assignment_count' => 0, |
||
| 60 | 'created_after_due_count' => 0, |
||
| 61 | 'gradeable_assignment_count' => 0, |
||
| 62 | 'graded_assignment_count' => 0, |
||
| 63 | 'zero_point_assignment_count' => 0, |
||
| 64 | 'analytics_page' => $_SESSION[CANVAS_INSTANCE_URL] . "/courses/{$course['id']}/external_tools/" . $toolbox->config(Toolbox::TOOL_CANVAS_EXTERNAL_TOOL_ID) |
||
| 65 | ); |
||
| 66 | |||
| 67 | $teacherIds = array(); |
||
| 68 | $teacherNames = array(); |
||
| 69 | $teachers = $toolbox->api_get( |
||
| 70 | "/courses/{$course['id']}/enrollments", |
||
| 71 | array( |
||
| 72 | 'type[]' => 'TeacherEnrollment' |
||
| 73 | ) |
||
| 74 | ); |
||
| 75 | foreach ($teachers as $teacher) { |
||
| 76 | $teacherIds[] = $teacher['user']['id']; |
||
| 77 | $teacherNames[] = $teacher['user']['sortable_name']; |
||
| 78 | } |
||
| 79 | $statistic['teacher[id]s'] = serialize($teacherIds); |
||
| 80 | $statistic['teacher[sortable_name]s'] = serialize($teacherNames); |
||
| 81 | |||
| 82 | $account = $toolbox->api_get("/accounts/{$course['account_id']}"); |
||
| 83 | $statistic['account[name]'] = $account['name']; |
||
| 84 | |||
| 85 | // ignore classes with no teachers (how do they even exist? weird.) |
||
| 86 | if (count($teacherIds) != 0) { |
||
| 87 | $statistic['student_count'] = 0; |
||
| 88 | $students = $toolbox->api_get( |
||
| 89 | "/courses/{$course['id']}/enrollments", |
||
| 90 | array( |
||
| 91 | 'type[]' => 'StudentEnrollment' |
||
| 92 | ) |
||
| 93 | ); |
||
| 94 | $statistic['student_count'] = $students->count(); |
||
| 95 | |||
| 96 | // ignore classes with no students |
||
| 97 | if ($statistic['student_count'] != 0) { |
||
| 98 | $assignments = $toolbox->api_get( |
||
| 99 | "/courses/{$course['id']}/assignments" |
||
| 100 | ); |
||
| 101 | |||
| 102 | $gradedSubmissionsCount = 0; |
||
| 103 | $turnAroundTimeTally = 0; |
||
| 104 | $leadTimeTally = 0; |
||
| 105 | $createdModifiedHistogram = array( |
||
| 106 | HISTOGRAM_CREATED => hoursRange(0, 86400, 3600, '', 0), |
||
| 107 | HISTOGRAM_MODIFIED => hoursRange(0, 86400, 3600, '', 0) |
||
| 108 | ); |
||
| 109 | |||
| 110 | foreach ($assignments as $assignment) { |
||
| 111 | // ignore unpublished assignments |
||
| 112 | if ($assignment['published'] == true) { |
||
| 113 | // check for due dates |
||
| 114 | $dueDate = new DateTime($assignment['due_at']); |
||
| 115 | $dueDate->setTimeZone(new DateTimeZone(SCHOOL_TIME_ZONE)); |
||
| 116 | if (($timestamp - $dueDate->getTimestamp()) > 0) { |
||
| 117 | $statistic['assignments_due_count']++; |
||
| 118 | |||
| 119 | // update created_modified_histogram |
||
| 120 | $createdAt = new DateTime($assignment['created_at']); |
||
| 121 | $createdAt->setTimeZone(new DateTimeZone(SCHOOL_TIME_ZONE)); |
||
| 122 | $updatedAt = new DateTime($assignment['updated_at']); |
||
| 123 | $updatedAt->setTimeZone(new DateTimeZone(SCHOOL_TIME_ZONE)); |
||
| 124 | $createdModifiedHistogram[HISTOGRAM_CREATED][$createdAt->format('g:00 a')]++; |
||
| 125 | if ($createdAt != $updatedAt) { |
||
| 126 | $createdModifiedHistogram[HISTOGRAM_MODIFIED][$updatedAt->format('g:00 a')]++; |
||
| 127 | } |
||
| 128 | |||
| 129 | // tally lead time on the assignment |
||
| 130 | $leadTimeTally += strtotime($assignment['due_at']) - strtotime($assignment['created_at']); |
||
| 131 | |||
| 132 | // was the assignment created after it was due? |
||
| 133 | if (strtotime($assignment['due_at']) < strtotime($assignment['created_at'])) { |
||
| 134 | $statistic['created_after_due_count']++; |
||
| 135 | } |
||
| 136 | |||
| 137 | // ignore ungraded assignments |
||
| 138 | if ($assignment['grading_type'] != 'not_graded') { |
||
| 139 | $statistic['gradeable_assignment_count']++; |
||
| 140 | $hasBeenGraded = false; |
||
| 141 | |||
| 142 | // tally zero point assignments |
||
| 143 | if ($assignment['points_possible'] == '0') { |
||
| 144 | $statistic['zero_point_assignment_count']++; |
||
| 145 | } |
||
| 146 | |||
| 147 | // build submission statistic |
||
| 148 | $submissions = $toolbox->api_get( |
||
| 149 | "/courses/{$course['id']}/assignments/{$assignment['id']}/submissions" |
||
| 150 | ); |
||
| 151 | foreach ($submissions as $submission) { |
||
| 152 | if ($submission['workflow_state'] == 'graded') { |
||
| 153 | if ($hasBeenGraded == false) { |
||
|
0 ignored issues
–
show
|
|||
| 154 | $hasBeenGraded = true; |
||
| 155 | $statistic['graded_assignment_count']++; |
||
| 156 | } |
||
| 157 | $gradedSubmissionsCount++; |
||
| 158 | $turnAroundTimeTally += max( |
||
| 159 | 0, |
||
| 160 | strtotime($submission['graded_at']) - strtotime($assignment['due_at']) |
||
| 161 | ); |
||
| 162 | } |
||
| 163 | } |
||
| 164 | |||
| 165 | if (!$hasBeenGraded) { |
||
| 166 | if (array_key_exists('oldest_ungraded_assignment_due_date', $statistic)) { |
||
| 167 | if (strtotime($assignment['due_at']) < strtotime($statistic['oldest_ungraded_assignment_due_date'])) { |
||
| 168 | $statistic['oldest_ungraded_assignment_due_date'] = $assignment['due_at']; |
||
| 169 | $statistic['oldest_ungraded_assignment_url'] = $assignment['html_url']; |
||
| 170 | $statistic['oldest_ungraded_assignment_name'] = $assignment['name']; |
||
| 171 | } |
||
| 172 | } else { |
||
| 173 | $statistic['oldest_ungraded_assignment_due_date'] = $assignment['due_at']; |
||
| 174 | $statistic['oldest_ungraded_assignment_url'] = $assignment['html_url']; |
||
| 175 | $statistic['oldest_ungraded_assignment_name'] = $assignment['name']; |
||
| 176 | } |
||
| 177 | } |
||
| 178 | } |
||
| 179 | } else { |
||
| 180 | $statistic['dateless_assignment_count']++; |
||
| 181 | } |
||
| 182 | } |
||
| 183 | } |
||
| 184 | |||
| 185 | $statistic['created_modified_histogram'] = serialize($createdModifiedHistogram); |
||
| 186 | |||
| 187 | // calculate average submissions graded per assignment (if non-zero) |
||
| 188 | if ($statistic['gradeable_assignment_count'] && $statistic['student_count']) { |
||
| 189 | $statistic['average_submissions_graded'] = $gradedSubmissionsCount / ($statistic['gradeable_assignment_count'] * $statistic['student_count']); |
||
| 190 | } |
||
| 191 | |||
| 192 | // calculate the average lead-time on assignments |
||
| 193 | if ($statistic['assignments_due_count']) { |
||
| 194 | $statistic['average_assignment_lead_time'] = $leadTimeTally / $statistic['assignments_due_count'] / 60 / 60 / 24; |
||
| 195 | } |
||
| 196 | |||
| 197 | // calculate average grading turn-around per submission |
||
| 198 | if ($gradedSubmissionsCount) { |
||
| 199 | $statistic['average_grading_turn_around'] = $turnAroundTimeTally / $gradedSubmissionsCount / 60 / 60 / 24; |
||
| 200 | } |
||
| 201 | |||
| 202 | $query = "INSERT INTO `course_statistics`"; |
||
| 203 | $fields = array(); |
||
| 204 | $values = array(); |
||
| 205 | while (list($field, $value) = each($statistic)) { |
||
| 206 | $fields[] = $field; |
||
| 207 | $values[] = $value; |
||
| 208 | } |
||
| 209 | $query .= ' (`' . implode('`, `', $fields) . "`) VALUES ('" . implode("', '", $values) . "')"; |
||
| 210 | $result = $toolbox->mysql_query($query); |
||
| 211 | } |
||
| 212 | } |
||
| 213 | } |
||
| 214 | } |
||
| 215 | |||
| 216 | /* force API configuration from config file */ |
||
| 217 | $toolbox->setApi(new CanvasPest( |
||
| 218 | $_SESSION[CANVAS_INSTANCE_URL] . '/api/v1', |
||
| 219 | $toolbox->config(Toolbox::TOOL_CANVAS_API)['token'] |
||
| 220 | )); |
||
| 221 | |||
| 222 | /* collect data on terms currently in session */ |
||
| 223 | try { |
||
| 224 | $terms = $toolbox->api_get('accounts/1/terms'); |
||
| 225 | $now = strtotime('now'); |
||
| 226 | foreach ($terms['enrollment_terms'] as $term) { |
||
| 227 | if (isset($term['start_at']) && isset($term['end_at'])) { |
||
| 228 | if ((strtotime($term['start_at']) <= $now) && ($now <= strtotime($term['end_at']))) { |
||
| 229 | collectStatistics($term['id'], $toolbox); |
||
| 230 | } |
||
| 231 | } |
||
| 232 | } |
||
| 233 | } catch (Exception $e) { |
||
| 234 | echo $e->getMessage(); |
||
| 235 | } |
||
| 236 |
When comparing two booleans, it is generally considered safer to use the strict comparison operator.