From 9c77f4bd9f27d0c177a1fb315403a4b05e5018a7 Mon Sep 17 00:00:00 2001 From: Tim Steiner <tsteiner2@unl.edu> Date: Fri, 14 Dec 2012 15:57:43 -0600 Subject: [PATCH] Modify MakeOfficial to also find and update any changed course codes. --- .../ApprovalActionMakeOfficialModel.php | 24 +++++ .../modules/courses/models/CourseModel.php | 95 +++++++++++++++++++ 2 files changed, 119 insertions(+) diff --git a/application/modules/courses/models/ApprovalActionMakeOfficialModel.php b/application/modules/courses/models/ApprovalActionMakeOfficialModel.php index 87f2451c..a2a50516 100644 --- a/application/modules/courses/models/ApprovalActionMakeOfficialModel.php +++ b/application/modules/courses/models/ApprovalActionMakeOfficialModel.php @@ -105,6 +105,30 @@ class Courses_ApprovalActionMakeOfficialModel extends Requests_ApprovalActionMod Requests_RequestModel::save($requests); $courses = Courses_CourseModel::findLatestOfRequest($requests); + $parentCourses = Courses_CourseModel::findParentOfRequest($requests); + + // Update all references to changed course codes in other courses. + foreach ($requests as $request) { + $course = $courses[$request->getId()]; + $parentCourse = $parentCourses[$request->getId()]; + if (!$parentCourse) { + continue; + } + + foreach ($course->getChangedCourseCodes($parentCourse) as $change) { + if ($change['from']['subject'] != $change['to']['subject']) { + continue; + } + Courses_CourseModel::updateCourseNumber( + $change['from']['subject'], + $change['from']['courseNumber'], + $change['from']['courseLetter'], + $change['to']['courseNumber'], + $change['to']['courseLetter'] + ); + } + } + foreach ($courses as $course) { $course->setType('official'); } diff --git a/application/modules/courses/models/CourseModel.php b/application/modules/courses/models/CourseModel.php index bd06fce7..ce627ffe 100644 --- a/application/modules/courses/models/CourseModel.php +++ b/application/modules/courses/models/CourseModel.php @@ -3645,5 +3645,100 @@ class Courses_CourseModel extends Unl_Model ) ); } + + public function getChangedCourseCodes(self $parentCourse = NULL) + { + if (!$parentCourse) { + return array(); + } + + $parentCrosslistings = array(); + foreach ($parentCourse->getCrosslistings() as $crosslisting) { + $parentCrosslistings[$crosslisting['type']][$crosslisting['subject']][] = array( + 'subject' => $crosslisting['subject'], + 'courseNumber' => $crosslisting['courseNumber'], + 'courseLetter' => $crosslisting['courseLetter'] + ); + usort($parentCrosslistings[$crosslisting['type']][$crosslisting['subject']], function($a, $b) { + return strcmp($a['courseNumber'] . $a['courseLetter'], $b['courseNumber'] . $b['courseLetter']); + }); + ksort($parentCrosslistings[$crosslisting['type']]); + } + + $currentCrosslistings = array(); + foreach ($this->getCrosslistings() as $crosslisting) { + $currentCrosslistings[$crosslisting['type']][$crosslisting['subject']][] = array( + 'subject' => $crosslisting['subject'], + 'courseNumber' => $crosslisting['courseNumber'], + 'courseLetter' => $crosslisting['courseLetter'] + ); + usort($currentCrosslistings[$crosslisting['type']][$crosslisting['subject']], function($a, $b) { + return strcmp($a['courseNumber'] . $a['courseLetter'], $b['courseNumber'] . $b['courseLetter']); + }); + ksort($currentCrosslistings[$crosslisting['type']]); + } + + foreach ($parentCrosslistings as $type => $p) { + foreach ($p as $subject => $courseNumbers) { + foreach ($courseNumbers as $courseNumber) { + if (($key = array_search($courseNumber, $currentCrosslistings[$type][$subject])) !== FALSE) { + unset($currentCrosslistings[$type][$subject][$key]); + } + } + } + } + foreach ($currentCrosslistings as $type => $p) { + foreach ($p as $subject => $courseNumbers) { + foreach ($courseNumbers as $courseNumber) { + if (($key = array_search($courseNumber, $parentCrosslistings[$type][$subject])) !== FALSE) { + unset($parentCrosslistings[$type][$subject][$key]); + } + } + } + } + + $changes = array(); + $map = function($fromNumbers, $toNumbers) use (&$map, &$changes) { + if (count($fromNumbers) == 0 || count($toNumbers) == 0) { + return array(); + } + + $minDiff = 9999999; + $minTiebreaker = 9999999; + foreach ($fromNumbers as $fromKey => $fromNumber) { + foreach ($toNumbers as $toKey => $toNumber) { + $diff = levenshtein(implode('', $fromNumber), implode('', $toNumber)); + $tieBreaker = abs($fromNumber['courseNumber'] - $toNumber['courseNumber']); + if ($diff <= $minDiff && $tieBreaker < $minTiebreaker) { + $minDiff = $diff; + $minTiebreaker = $tieBreaker; + $finalFromKey = $fromKey; + $finalToKey = $toKey; + } + } + } + + $change = array( + 'from' => $fromNumbers[$finalFromKey], + 'to' => $toNumbers[$finalToKey], + ); + + unset($fromNumbers[$finalFromKey]); + unset($toNumbers[$finalToKey]); + + $changes += $map($fromNumbers, $toNumbers); + $changes[] = $change; + + return $changes; + }; + + foreach ($parentCrosslistings as $type => $p) { + foreach ($p as $subject => $courseNumbers) { + $map($courseNumbers, $currentCrosslistings[$type][$subject]); + } + } + + return $changes; + } } -- GitLab